Exemple #1
0
def call_signing(file_obj):
    """Get the jar signature and send it to the signing server to be signed."""
    endpoint = get_endpoint(file_obj)
    if not endpoint:
        log.warning('Not signing: no active endpoint')
        return

    timeout = settings.SIGNING_SERVER_TIMEOUT

    # We only want the (unique) temporary file name.
    with tempfile.NamedTemporaryFile() as temp_file:
        temp_filename = temp_file.name

    # Extract jar signature.
    try:
        jar = JarExtractor(path=storage.open(file_obj.file_path),
                           outpath=temp_filename,
                           omit_signature_sections=True)
    except:
        msg = 'Archive extraction failed. Bad archive?'
        log.error(msg, exc_info=True)
        raise SigningError(msg)

    log.info('File signature contents: %s' % jar.signatures)

    addon_id = file_obj.version.addon.guid

    log.info('Calling signing service: %s' % endpoint)
    try:
        with statsd.timer('services.sign.addon'):
            response = requests.post(endpoint, timeout=timeout,
                                     data={'addon_id': addon_id},
                                     files={'file': ('mozilla.sf',
                                                     str(jar.signatures))})
    except requests.exceptions.HTTPError as error:
        # Will occur when a 3xx or greater code is returned.
        msg = 'Posting to add-on signing failed: %s, %s' % (
            error.response.status, error)
        log.error(msg)
        raise SigningError(msg)
    except:
        # Will occur when some other error occurs.
        msg = 'Posting to add-on signing failed'
        log.error(msg, exc_info=True)
        raise SigningError(msg)
    if response.status_code != 200:
        msg = 'Posting to add-on signing failed: %s' % response.reason
        log.error(msg)
        raise SigningError(msg)

    pkcs7 = b64decode(json.loads(response.content)['mozilla.rsa'])
    try:
        cert_serial_num = get_signature_serial_number(pkcs7)
        jar.make_signed(pkcs7, sigpath='mozilla')
    except:
        msg = 'Addon signing failed'
        log.error(msg, exc_info=True)
        raise SigningError(msg)
    shutil.move(temp_filename, file_obj.file_path)
    return cert_serial_num
Exemple #2
0
def call_signing(file_path, endpoint, auth):
    """Get the jar signature and send it to the signing server to be signed."""

    # We only want the (unique) temporary file name.
    with tempfile.NamedTemporaryFile() as temp_file:
        temp_filename = temp_file.name

    # Extract jar signature.
    jar = JarExtractor(path=file_path,
                       outpath=temp_filename,
                       omit_signature_sections=True,
                       extra_newlines=True)

    response = requests.post(
        endpoint,
        auth=auth,
        files={'file': (u'mozilla.sf', unicode(jar.signatures))})

    if response.status_code != 200:
        msg = u'Posting to add-on signing failed: {0}'.format(response.reason)
        raise SigningError(msg)

    pkcs7 = b64decode(json.loads(response.content)['mozilla.rsa'])
    jar.make_signed(pkcs7, sigpath=u'mozilla')
    shutil.move(temp_filename, file_path)

    print "{0} signed!".format(file_path)
    def test_make_signed_default_sigpath(self):
        extracted = JarExtractor(get_file('test-jar.zip'))
        # Not a valid signature but a PKCS7 data blob, at least
        with open(get_file('zigbert.test.pkcs7.der'), 'rb') as f:
            signature = f.read()
            signature_digest = sha1()
            signature_digest.update(signature)

        signed_file = self.tmp_file('test-jar-signed.zip')
        extracted.make_signed(signed_manifest=str(extracted.signatures),
                              signature=signature,
                              outpath=signed_file,
                              sigpath='zigbert')

        with ZipFile(signed_file, 'r') as zin:
            files = [
                'test-file', 'META-INF/manifest.mf', 'META-INF/zigbert.rsa',
                'META-INF/zigbert.sf', 'test-dir/', 'test-dir/nested-test-file'
            ]
            zfiles = sorted([z.filename for z in zin.filelist], key=file_key)
            self.assertEqual(files, zfiles)
            zip_sig_digest = sha1()
            zip_sig_digest.update(zin.read('META-INF/zigbert.rsa'))

            self.assertEqual(signature_digest.hexdigest(),
                             zip_sig_digest.hexdigest())

        signed = JarExtractor(signed_file)
        self.assertEqual(force_bytes(extracted.manifest),
                         force_bytes(signed.manifest))
Exemple #4
0
def call_signing(file_obj, endpoint):
    """Get the jar signature and send it to the signing server to be signed."""
    # We only want the (unique) temporary file name.
    with tempfile.NamedTemporaryFile() as temp_file:
        temp_filename = temp_file.name

    # Extract jar signature.
    jar = JarExtractor(path=storage.open(file_obj.file_path),
                       outpath=temp_filename,
                       omit_signature_sections=True,
                       extra_newlines=True)

    log.debug(u'File signature contents: {0}'.format(jar.signatures))

    log.debug(u'Calling signing service: {0}'.format(endpoint))
    with statsd.timer('services.sign.addon'):
        response = requests.post(
            endpoint,
            timeout=settings.SIGNING_SERVER_TIMEOUT,
            data={'addon_id': get_id(file_obj.version.addon)},
            files={'file': (u'mozilla.sf', unicode(jar.signatures))})
    if response.status_code != 200:
        msg = u'Posting to add-on signing failed: {0}'.format(response.reason)
        log.error(msg)
        raise SigningError(msg)

    pkcs7 = b64decode(json.loads(response.content)['mozilla.rsa'])
    cert_serial_num = get_signature_serial_number(pkcs7)
    jar.make_signed(pkcs7, sigpath=u'mozilla')
    shutil.move(temp_filename, file_obj.file_path)
    return cert_serial_num
    def test_make_signed(self):
        extracted = JarExtractor(get_file('test-jar.zip'))
        # Not a valid signature but a PKCS7 data blob, at least
        with open(get_file('zigbert.test.pkcs7.der'), 'rb') as f:
            signature = f.read()
            signature_digest = sha1()
            signature_digest.update(signature)

        signed_file = self.tmp_file('test-jar-signed.zip')
        sigpath = 'zoidberg'
        extracted.make_signed(signed_manifest=str(extracted.signatures),
                              signature=signature,
                              outpath=signed_file,
                              sigpath=sigpath)
        # Now verify the signed zipfile's contents
        with ZipFile(signed_file, 'r') as zin:
            # sorted(...) should result in the following order:
            files = [
                'test-file', 'META-INF/manifest.mf', 'META-INF/zoidberg.rsa',
                'META-INF/zoidberg.sf', 'test-dir/',
                'test-dir/nested-test-file'
            ]
            zfiles = sorted([z.filename for z in zin.filelist], key=file_key)
            self.assertEqual(files, zfiles)
            zip_sig_digest = sha1()
            zip_sig_digest.update(zin.read('META-INF/zoidberg.rsa'))

            self.assertEqual(signature_digest.hexdigest(),
                             zip_sig_digest.hexdigest())
        # And make sure the manifest is correct
        signed = JarExtractor(signed_file)
        self.assertEqual(force_bytes(extracted.manifest),
                         force_bytes(signed.manifest))
Exemple #6
0
 def test_11_make_signed(self):
     extracted = JarExtractor(test_file('test-jar.zip'),
                              omit_signature_sections=True)
     # Not a valid signature but a PKCS7 data blob, at least
     with open(test_file('zigbert.test.pkcs7.der'), 'r') as f:
         signature = f.read()
         signature_digest = sha.new(signature)
     signed_file = self.tmp_file('test-jar-signed.zip')
     sigpath = 'zoidberg'
     extracted.make_signed(signature, signed_file, sigpath=sigpath)
     # Now verify the signed zipfile's contents
     with ZipFile(signed_file, 'r') as zin:
         # sorted(...) should result in the following order:
         files = [
             'test-file', 'META-INF/manifest.mf',
             'META-INF/%s.rsa' % sigpath,
             'META-INF/%s.sf' % sigpath, 'test-dir/',
             'test-dir/nested-test-file'
         ]
         zfiles = [f.filename for f in sorted(zin.filelist, key=file_key)]
         self.assertEqual(files, zfiles)
         zip_sig_digest = sha.new(zin.read('META-INF/%s.rsa' % sigpath))
         self.assertEqual(signature_digest.hexdigest(),
                          zip_sig_digest.hexdigest())
     # And make sure the manifest is correct
     signed = JarExtractor(signed_file, omit_signature_sections=True)
     self.assertEqual(str(extracted.manifest), str(signed.manifest))
Exemple #7
0
    def test_make_signed(self):
        extracted = JarExtractor(get_file('test-jar.zip'))
        # Not a valid signature but a PKCS7 data blob, at least
        with open(get_file('zigbert.test.pkcs7.der'), 'rb') as f:
            signature = f.read()
            signature_digest = sha1()
            signature_digest.update(signature)

        signed_file = self.tmp_file('test-jar-signed.zip')
        sigpath = 'zoidberg'
        extracted.make_signed(
            signed_manifest=str(extracted.signatures),
            signature=signature,
            outpath=signed_file,
            sigpath=sigpath
        )
        # Now verify the signed zipfile's contents
        with ZipFile(signed_file, 'r') as zin:
            # sorted(...) should result in the following order:
            files = ['test-file', 'META-INF/manifest.mf',
                     'META-INF/zoidberg.rsa',
                     'META-INF/zoidberg.sf',
                     'test-dir/', 'test-dir/nested-test-file']
            zfiles = sorted([z.filename for z in zin.filelist], key=file_key)
            self.assertEqual(files, zfiles)
            zip_sig_digest = sha1()
            zip_sig_digest.update(zin.read('META-INF/zoidberg.rsa'))

            self.assertEqual(signature_digest.hexdigest(),
                             zip_sig_digest.hexdigest())
        # And make sure the manifest is correct
        signed = JarExtractor(signed_file)
        self.assertEqual(force_bytes(extracted.manifest), force_bytes(signed.manifest))
Exemple #8
0
    def test_make_signed_default_sigpath(self):
        extracted = JarExtractor(get_file('test-jar.zip'))
        # Not a valid signature but a PKCS7 data blob, at least
        with open(get_file('zigbert.test.pkcs7.der'), 'rb') as f:
            signature = f.read()
            signature_digest = sha1()
            signature_digest.update(signature)

        signed_file = self.tmp_file('test-jar-signed.zip')
        extracted.make_signed(
            signed_manifest=str(extracted.signatures),
            signature=signature,
            outpath=signed_file,
            sigpath='zigbert'
        )

        with ZipFile(signed_file, 'r') as zin:
            files = ['test-file', 'META-INF/manifest.mf',
                     'META-INF/zigbert.rsa',
                     'META-INF/zigbert.sf',
                     'test-dir/', 'test-dir/nested-test-file']
            zfiles = sorted([z.filename for z in zin.filelist], key=file_key)
            self.assertEqual(files, zfiles)
            zip_sig_digest = sha1()
            zip_sig_digest.update(zin.read('META-INF/zigbert.rsa'))

            self.assertEqual(signature_digest.hexdigest(),
                             zip_sig_digest.hexdigest())

        signed = JarExtractor(signed_file)
        self.assertEqual(force_bytes(extracted.manifest), force_bytes(signed.manifest))
def call_signing(file_obj, endpoint):
    """Get the jar signature and send it to the signing server to be signed."""
    # We only want the (unique) temporary file name.
    with tempfile.NamedTemporaryFile() as temp_file:
        temp_filename = temp_file.name

    # Extract jar signature.
    jar = JarExtractor(path=storage.open(file_obj.file_path),
                       outpath=temp_filename,
                       omit_signature_sections=True,
                       extra_newlines=True)

    log.debug(u'File signature contents: {0}'.format(jar.signatures))

    log.debug(u'Calling signing service: {0}'.format(endpoint))
    with statsd.timer('services.sign.addon'):
        response = requests.post(
            endpoint,
            timeout=settings.SIGNING_SERVER_TIMEOUT,
            data={'addon_id': get_id(file_obj.version.addon)},
            files={'file': (u'mozilla.sf', unicode(jar.signatures))})
    if response.status_code != 200:
        msg = u'Posting to add-on signing failed: {0}'.format(response.reason)
        log.error(msg)
        raise SigningError(msg)

    pkcs7 = b64decode(json.loads(response.content)['mozilla.rsa'])
    cert_serial_num = get_signature_serial_number(pkcs7)
    jar.make_signed(pkcs7, sigpath=u'mozilla')
    shutil.move(temp_filename, file_obj.file_path)
    return cert_serial_num
Exemple #10
0
def call_signing(file_path, endpoint, auth):
    """Get the jar signature and send it to the signing server to be signed."""

    # We only want the (unique) temporary file name.
    with tempfile.NamedTemporaryFile() as temp_file:
        temp_filename = temp_file.name

    # Extract jar signature.
    jar = JarExtractor(path=file_path,
                       outpath=temp_filename,
                       omit_signature_sections=True,
                       extra_newlines=True)

    response = requests.post(endpoint,
                             auth=auth,
                             files={'file': (u'mozilla.sf',
                                    unicode(jar.signatures))})

    if response.status_code != 200:
        msg = u'Posting to add-on signing failed: {0}'.format(response.reason)
        raise SigningError(msg)

    pkcs7 = b64decode(json.loads(response.content)['mozilla.rsa'])
    jar.make_signed(pkcs7, sigpath=u'mozilla')
    shutil.move(temp_filename, file_path)

    print "{0} signed!".format(file_path)
Exemple #11
0
def autograph_sign_data(file_obj):
    """Sign `file_obj` via autographs /sign/data endpoint.

    .. note::

        This endpoint usage is being replaced by `autograph_sign_file`.

    :returns: The certificates serial number.
    """
    conf = settings.AUTOGRAPH_CONFIG

    jar = JarExtractor(path=storage.open(file_obj.current_file_path))

    log.debug(u'File signature contents: {0}'.format(jar.signatures))

    signed_manifest = six.text_type(jar.signatures)

    signing_request = [{
        'input':
        force_text(b64encode(force_bytes(signed_manifest))),
        'keyid':
        conf['signer'],
        'options': {
            'id': get_id(file_obj.version.addon),
        },
    }]

    with statsd.timer('services.sign.addon.autograph'):
        response = requests.post(
            '{server}/sign/data'.format(server=conf['server_url']),
            json=signing_request,
            auth=HawkAuth(id=conf['user_id'], key=conf['key']))

    if response.status_code != requests.codes.CREATED:
        msg = u'Posting to add-on signing failed: {0} {1}'.format(
            response.reason, response.text)
        log.error(msg)
        raise SigningError(msg)

    # convert the base64 encoded pkcs7 signature back to binary
    pkcs7 = b64decode(force_bytes(response.json()[0]['signature']))

    cert_serial_num = get_signer_serial_number(pkcs7)

    # We only want the (unique) temporary file name.
    with tempfile.NamedTemporaryFile(dir=settings.TMP_PATH) as temp_file:
        temp_filename = temp_file.name

    jar.make_signed(signed_manifest=signed_manifest,
                    signature=pkcs7,
                    sigpath=u'mozilla',
                    outpath=temp_filename)
    shutil.move(temp_filename, file_obj.current_file_path)

    return cert_serial_num
Exemple #12
0
def autograph_sign_data(file_obj):
    """Sign `file_obj` via autographs /sign/data endpoint.

    .. note::

        This endpoint usage is being replaced by `autograph_sign_file`.

    :returns: The certificates serial number.
    """
    conf = settings.AUTOGRAPH_CONFIG

    jar = JarExtractor(path=storage.open(file_obj.current_file_path))

    log.debug(u'File signature contents: {0}'.format(jar.signatures))

    signed_manifest = six.text_type(jar.signatures)

    signing_request = [{
        'input': force_text(b64encode(force_bytes(signed_manifest))),
        'keyid': conf['signer'],
        'options': {
            'id': get_id(file_obj.version.addon),
        },
    }]

    with statsd.timer('services.sign.addon.autograph'):
        response = requests.post(
            '{server}/sign/data'.format(server=conf['server_url']),
            json=signing_request,
            auth=HawkAuth(id=conf['user_id'], key=conf['key']))

    if response.status_code != requests.codes.CREATED:
        msg = u'Posting to add-on signing failed: {0} {1}'.format(
            response.reason, response.text)
        log.error(msg)
        raise SigningError(msg)

    # convert the base64 encoded pkcs7 signature back to binary
    pkcs7 = b64decode(force_bytes(response.json()[0]['signature']))

    cert_serial_num = get_signer_serial_number(pkcs7)

    # We only want the (unique) temporary file name.
    with tempfile.NamedTemporaryFile(dir=settings.TMP_PATH) as temp_file:
        temp_filename = temp_file.name

    jar.make_signed(
        signed_manifest=signed_manifest,
        signature=pkcs7,
        sigpath=u'mozilla',
        outpath=temp_filename)
    shutil.move(temp_filename, file_obj.current_file_path)

    return cert_serial_num
Exemple #13
0
def call_signing(file_obj):
    """Get the jar signature and send it to the signing server to be signed."""
    # Extract jar signature.
    jar = JarExtractor(path=storage.open(file_obj.current_file_path))

    log.debug(u'File signature contents: {0}'.format(jar.signatures))

    signed_manifest = six.text_type(jar.signatures)

    conf = settings.AUTOGRAPH_CONFIG
    log.debug('Calling autograph service: {0}'.format(conf['server_url']))

    # create the signing request
    signing_request = [{
        'input': b64encode(signed_manifest),
        'keyid': conf['signer'],
        'options': {
            'id': get_id(file_obj.version.addon),
        },
    }]

    # post the request
    with statsd.timer('services.sign.addon.autograph'):
        response = requests.post(
            '{server}/sign/data'.format(server=conf['server_url']),
            json=signing_request,
            auth=HawkAuth(id=conf['user_id'], key=conf['key']))

    if response.status_code != requests.codes.CREATED:
        msg = u'Posting to add-on signing failed: {0} {1}'.format(
            response.reason, response.text)
        log.error(msg)
        raise SigningError(msg)

    # convert the base64 encoded pkcs7 signature back to binary
    pkcs7 = b64decode(force_bytes(response.json()[0]['signature']))

    cert_serial_num = get_signer_serial_number(pkcs7)

    # We only want the (unique) temporary file name.
    with tempfile.NamedTemporaryFile(dir=settings.TMP_PATH) as temp_file:
        temp_filename = temp_file.name

    jar.make_signed(
        signed_manifest=signed_manifest,
        signature=pkcs7,
        sigpath=u'mozilla',
        outpath=temp_filename)
    shutil.move(temp_filename, file_obj.current_file_path)
    return cert_serial_num
Exemple #14
0
def call_signing(file_obj):
    """Get the jar signature and send it to the signing server to be signed."""
    # Extract jar signature.
    jar = JarExtractor(path=storage.open(file_obj.file_path))

    log.debug(u'File signature contents: {0}'.format(jar.signatures))

    signed_manifest = unicode(jar.signatures)

    conf = settings.AUTOGRAPH_CONFIG
    log.debug('Calling autograph service: {0}'.format(conf['server_url']))

    # create the signing request
    signing_request = [{
        'input': b64encode(signed_manifest),
        'keyid': conf['signer'],
        'options': {
            'id': get_id(file_obj.version.addon),
        },
    }]

    # post the request
    with statsd.timer('services.sign.addon.autograph'):
        response = requests.post(
            '{server}/sign/data'.format(server=conf['server_url']),
            json=signing_request,
            auth=HawkAuth(id=conf['user_id'], key=conf['key']))

    if response.status_code != requests.codes.CREATED:
        msg = u'Posting to add-on signing failed: {0} {1}'.format(
            response.reason, response.text)
        log.error(msg)
        raise SigningError(msg)

    # convert the base64 encoded pkcs7 signature back to binary
    pkcs7 = b64decode(force_bytes(response.json()[0]['signature']))

    cert_serial_num = get_signer_serial_number(pkcs7)

    # We only want the (unique) temporary file name.
    with tempfile.NamedTemporaryFile(dir=settings.TMP_PATH) as temp_file:
        temp_filename = temp_file.name

    jar.make_signed(
        signed_manifest=signed_manifest,
        signature=pkcs7,
        sigpath=u'mozilla',
        outpath=temp_filename)
    shutil.move(temp_filename, file_obj.file_path)
    return cert_serial_num
Exemple #15
0
 def test_10_resigning_manifest_exclusions(self):
     # This zip contains META-INF/manifest.mf, META-INF/zigbert.sf, and
     # META-INF/zigbert.rsa in addition to the contents of the basic test
     # archive test-jar.zip
     extracted = JarExtractor(test_file('test-jar-meta-inf-exclude.zip'),
                              omit_signature_sections=True)
     self.assertEqual(str(extracted.manifest), MANIFEST)
Exemple #16
0
def sign_app(src, dest, reviewer=False):
    """
    Generate a manifest and signature and send signature to signing server to
    be signed.
    """
    active_endpoint = _get_endpoint(reviewer)
    timeout = settings.SIGNED_APPS_SERVER_TIMEOUT

    if not active_endpoint:
        _no_sign(src, dest)
        return

    # Extract necessary info from the archive
    try:
        jar = JarExtractor(
            storage.open(src, 'r'), storage.open(dest, 'w'),
            omit_signature_sections=settings.SIGNED_APPS_OMIT_PER_FILE_SIGS)
    except:
        log.error('Archive extraction failed. Bad archive?', exc_info=True)
        raise SigningError('Archive extraction failed. Bad archive?')

    log.info('App signature contents: %s' % jar.signatures)

    log.info('Calling service: %s' % active_endpoint)
    try:
        with statsd.timer('services.sign.app'):
            response = requests.post(active_endpoint, timeout=timeout,
                                     files={'file': ('zigbert.sf',
                                                     str(jar.signatures))})
    except requests.exceptions.HTTPError, error:
        # Will occur when a 3xx or greater code is returned.
        log.error('Posting to app signing failed: %s, %s' % (
            error.response.status, error))
        raise SigningError('Posting to app signing failed: %s, %s' % (
            error.response.status, error))
Exemple #17
0
async def call_signing(session):
    """Get the jar signature and send it to the signing server to be signed."""

    # We only want the (unique) temporary file name.
    with tempfile.NamedTemporaryFile() as temp_file:
        temp_filename = temp_file.name

    # Extract jar signature.
    jar = JarExtractor(path=PATH_XPI)
    signed_manifest = jar.signatures

    # create the signing request
    sigreq = [{
        "input":
        bytes(b64encode(str(
            jar.signatures).encode("utf-8"))).decode("utf-8"),  # noqa
        "keyid":
        SIGNER,
        "options": {
            "id": GUID,
        },
    }]

    # post the request
    signer = Signer(id=HAWK_ID, key=HAWK_KEY)
    async with aiohttp.ClientSession() as session:
        session = signer(session)
        resp = await session.post(TARGET, data=sigreq)
        try:
            sigresp = await resp.json()
        except Exception:
            sigresp = {'error': (await resp.text())}

        assert resp.status == 201, \
            'Posting to add-on signing failed:{0}'.format(json.dumps(sigresp))

        # convert the base64 encoded pkcs7 signature back to binary
        pkcs7 = b64decode(sigresp[0]["signature"])
        jar.make_signed(signed_manifest=str(signed_manifest).encode("utf-8"),
                        signature=pkcs7,
                        sigpath=u'mozilla',
                        outpath=temp_filename)

        shutil.move(temp_filename, PATH_XPI)

        print("{0} signed!".format(PATH_XPI))
Exemple #18
0
def call_signing(file_path, guid, endpoint, signer, user, key):
    """Get the jar signature and send it to the signing server to be signed."""

    # We only want the (unique) temporary file name.
    with tempfile.NamedTemporaryFile() as temp_file:
        temp_filename = temp_file.name

    # Extract jar signature.
    jar = JarExtractor(path=file_path)
    signed_manifest = jar.signatures

    # create the signing request
    sigreq = [{
        "input":
        bytes(b64encode(str(jar.signatures).encode("utf-8"))).decode("utf-8"),
        "keyid":
        signer,
        "options": {
            "id": guid,
        },
    }]

    # post the request
    response = requests.post(endpoint,
                             json=sigreq,
                             auth=HawkAuth(id=user, key=key))

    # convert the base64 encoded pkcs7 signature back to binary
    if response.status_code != 201:
        print('Posting to add-on signing failed: {0}'.format(response.text))
        exit(1)

    sigresp = json.loads(response.text)
    pkcs7 = b64decode(sigresp[0]["signature"])
    jar.make_signed(signed_manifest=str(signed_manifest).encode("utf-8"),
                    signature=pkcs7,
                    sigpath=u'mozilla',
                    outpath=temp_filename)
    shutil.move(temp_filename, file_path)

    print("{0} signed!".format(file_path))
Exemple #19
0
def sign_xpi(env, localfile, guid):
    """
    Use the Autograph service to sign the XPI.

    :returns: filename of the signed XPI
    """
    jar_extractor = JarExtractor(localfile, extra_newlines=True)
    auth = HawkAuth(id=env['autograph_hawk_id'],
                    key=env['autograph_hawk_secret'])
    b64_payload = base64.b64encode(jar_extractor.signature)
    url = urljoin(env['autograph_server_url'], '/sign/data')
    key_id = env['autograph_key_id']
    resp = requests.post(
        url,
        auth=auth,
        json=[{
            # FIXME: not Python 3 safe, but signing-clients only supports
            # Python 2.7 anyhow so whatever
            "input": b64_payload,
            "keyid": key_id,
            "options": {
                "id": guid,
            }
        }])
    resp.raise_for_status()
    signature = base64.b64decode(resp.json()[0]['signature'])

    # FIXME: make_signed doesn't support NamedTemporaryFile or
    # anything like that; we have to provide an actual filename.
    # Try to generate a sensible filename.
    # FIXME: I guess the caller has to remember to delete this file.
    # Hopefully there's no other calls to a similarly-named file??
    (localstem, localext) = os.path.splitext(localfile.name)
    output_file = localstem + '-signed' + localext

    jar_extractor.make_signed(signature, output_file, sigpath="mozilla.rsa")
    return output_file
    def test_make_signed_refuses_weird_sigpath(self):
        extracted = JarExtractor(get_file('test-jar.zip'))

        # Hardcode the parameters we don't care about in this test
        signed_manifest = 'abc'
        signature = 'signed: abc'
        outpath = 'signed-jar.zip'

        def make_signed(sigpath):
            return extracted.make_signed(signed_manifest=signed_manifest,
                                         signature=signature,
                                         outpath=outpath,
                                         sigpath=sigpath)

        self.assertRaises(ValueError, make_signed, 'subdirectory/filename')
        self.assertRaises(ValueError, make_signed, 'filename.abc')
Exemple #21
0
def call_signing(file_obj):
    """Get the jar signature and send it to the signing server to be signed."""
    endpoint = get_endpoint(file_obj)
    if not endpoint:
        log.warning('Not signing: no active endpoint')
        return

    timeout = settings.SIGNING_SERVER_TIMEOUT

    # We only want the (unique) temporary file name.
    with tempfile.NamedTemporaryFile() as temp_file:
        temp_filename = temp_file.name

    # Extract jar signature.
    try:
        jar = JarExtractor(path=storage.open(file_obj.file_path),
                           outpath=temp_filename,
                           omit_signature_sections=True)
    except:
        msg = 'Archive extraction failed. Bad archive?'
        log.error(msg, exc_info=True)
        raise SigningError(msg)

    log.info('File signature contents: %s' % jar.signatures)

    # From https://wiki.mozilla.org/AMO/SigningService/API:
    # "A unique identifier for the combination of addon name and version that
    # will be used in the generated key and certificate. A strong preference
    # for human readable.
    addon_id = u"{slug}-{version}".format(slug=file_obj.version.addon.slug,
                                          version=file_obj.version.version)

    log.info('Calling signing service: %s' % endpoint)
    try:
        with statsd.timer('services.sign.addon'):
            response = requests.post(
                endpoint,
                timeout=timeout,
                data={'addon_id': addon_id},
                files={'file': ('zigbert.sf', str(jar.signatures))})
    except requests.exceptions.HTTPError as error:
        # Will occur when a 3xx or greater code is returned.
        msg = 'Posting to add-on signing failed: %s, %s' % (
            error.response.status, error)
        log.error(msg)
        raise SigningError(msg)
    except:
        # Will occur when some other error occurs.
        msg = 'Posting to add-on signing failed'
        log.error(msg, exc_info=True)
        raise SigningError(msg)
    if response.status_code != 200:
        msg = 'Posting to add-on signing failed %s' % response.reason
        log.error(msg)
        raise SigningError(msg)

    pkcs7 = b64decode(json.loads(response.content)['zigbert.rsa'])
    try:
        cert_serial_num = get_signature_serial_number(pkcs7)
        jar.make_signed(pkcs7)
    except:
        msg = 'Addon signing failed'
        log.error(msg, exc_info=True)
        raise SigningError(msg)
    shutil.move(temp_filename, file_obj.file_path)
    return cert_serial_num
Exemple #22
0
def call_signing(file_obj):
    """Get the jar signature and send it to the signing server to be signed."""
    # Extract jar signature.
    jar = JarExtractor(path=storage.open(file_obj.file_path))

    log.debug(u'File signature contents: {0}'.format(jar.signatures))

    use_autograph = waffle.switch_is_active('activate-autograph-signing')
    signed_manifest = unicode(jar.signatures)
    has_error = False

    if use_autograph:
        conf = settings.AUTOGRAPH_CONFIG
        log.debug('Calling autograph service: {0}'.format(conf['server_url']))

        # create the signing request
        signing_request = [{
            'input': b64encode(signed_manifest),
            'keyid': conf['signer'],
            'options': {
                'id': get_id(file_obj.version.addon),
            },
        }]

        # post the request
        with statsd.timer('services.sign.addon'):
            response = requests.post(
                '{server}/sign/data'.format(server=conf['server_url']),
                json=signing_request,
                auth=HawkAuth(id=conf['user_id'], key=conf['key']))

        if response.status_code != requests.codes.CREATED:
            has_error = True
    else:
        log.debug(u'Calling signing service: {0}'.format(
            settings.SIGNING_SERVER))

        with statsd.timer('services.sign.addon'):
            response = requests.post(
                get_trunion_endpoint(settings.SIGNING_SERVER),
                timeout=settings.SIGNING_SERVER_TIMEOUT,
                data={'addon_id': get_id(file_obj.version.addon)},
                files={'file': (u'mozilla.sf', signed_manifest)})

        if response.status_code != requests.codes.OK:
            has_error = True

    if has_error:
        msg = u'Posting to add-on signing failed: {0} {1}'.format(
            response.reason, response.text)
        log.error(msg)
        raise SigningError(msg)

    # convert the base64 encoded pkcs7 signature back to binary
    if use_autograph:
        pkcs7 = b64decode(force_bytes(response.json()[0]['signature']))
    else:
        pkcs7 = b64decode(response.json()['mozilla.rsa'])

    cert_serial_num = get_signer_serial_number(pkcs7)

    # We only want the (unique) temporary file name.
    with tempfile.NamedTemporaryFile() as temp_file:
        temp_filename = temp_file.name

    jar.make_signed(
        signed_manifest=signed_manifest,
        signature=pkcs7,
        sigpath=u'mozilla',
        outpath=temp_filename)
    shutil.move(temp_filename, file_obj.file_path)
    return cert_serial_num
 def _extract(self):
     return JarExtractor(get_file('test-jar.zip'))
Exemple #24
0
 def _extract(self, omit=False):
     return JarExtractor('signing_clients/tests/test-jar.zip',
                         'signing_clients/tests/test-jar-signed.jar',
                         omit_signature_sections=omit)
Exemple #25
0
 def test_07_wrapping(self):
     extracted = JarExtractor(
         'signing_clients/tests/test-jar-long-path.zip',
         'signing_clients/tests/test-jar-long-path-signed.jar',
         omit_signature_sections=False)
     self.assertEqual(str(extracted.manifest), VERY_LONG_MANIFEST)
 def test_wrapping(self):
     extracted = JarExtractor(get_file('test-jar-long-path.zip'))
     self.assertEqual(force_bytes(extracted.manifest), VERY_LONG_MANIFEST)
 def test_unicode(self):
     extracted = JarExtractor(get_file('test-jar-unicode.zip'))
     self.assertEqual(
         force_bytes(extracted.manifest).decode('utf-8'),
         UNICODE_MANIFEST + u"\n")
 def test_resigning_manifest_exclusions(self):
     # This zip contains META-INF/manifest.mf, META-INF/zigbert.sf, and
     # META-INF/zigbert.rsa in addition to the contents of the basic test
     # archive test-jar.zip
     extracted = JarExtractor(get_file('test-jar-meta-inf-exclude.zip'))
     self.assertEqual(force_bytes(extracted.manifest), MANIFEST + b"\n")
Exemple #29
0
 def test_08_unicode(self):
     extracted = JarExtractor(test_file('test-jar-unicode.zip'),
                              omit_signature_sections=False)
     self.assertEqual(str(extracted.manifest), UNICODE_MANIFEST)
Exemple #30
0
 def test_07_wrapping(self):
     extracted = JarExtractor(test_file('test-jar-long-path.zip'),
                              omit_signature_sections=False)
     self.assertEqual(str(extracted.manifest), VERY_LONG_MANIFEST)
Exemple #31
0
 def _extract(self, omit=False, newlines=False):
     return JarExtractor(test_file('test-jar.zip'),
                         omit_signature_sections=omit,
                         extra_newlines=newlines)
Exemple #32
0
def call_signing(file_obj):
    """Get the jar signature and send it to the signing server to be signed."""
    # Extract jar signature.
    jar = JarExtractor(path=storage.open(file_obj.file_path))

    log.debug(u'File signature contents: {0}'.format(jar.signatures))

    use_autograph = waffle.switch_is_active('activate-autograph-signing')
    signed_manifest = unicode(jar.signatures)
    has_error = False

    if use_autograph:
        conf = settings.AUTOGRAPH_CONFIG
        log.debug('Calling autograph service: {0}'.format(conf['server_url']))

        # create the signing request
        signing_request = [{
            'input': b64encode(signed_manifest),
            'keyid': conf['signer'],
            'options': {
                'id': get_id(file_obj.version.addon),
            },
        }]

        # post the request
        with statsd.timer('services.sign.addon'):
            response = requests.post(
                '{server}/sign/data'.format(server=conf['server_url']),
                json=signing_request,
                auth=HawkAuth(id=conf['user_id'], key=conf['key']))

        if response.status_code != requests.codes.CREATED:
            has_error = True
    else:
        log.debug(u'Calling signing service: {0}'.format(
            settings.SIGNING_SERVER))

        with statsd.timer('services.sign.addon'):
            response = requests.post(
                get_trunion_endpoint(settings.SIGNING_SERVER),
                timeout=settings.SIGNING_SERVER_TIMEOUT,
                data={'addon_id': get_id(file_obj.version.addon)},
                files={'file': (u'mozilla.sf', signed_manifest)})

        if response.status_code != requests.codes.OK:
            has_error = True

    if has_error:
        msg = u'Posting to add-on signing failed: {0} {1}'.format(
            response.reason, response.text)
        log.error(msg)
        raise SigningError(msg)

    # convert the base64 encoded pkcs7 signature back to binary
    if use_autograph:
        pkcs7 = b64decode(force_bytes(response.json()[0]['signature']))
    else:
        pkcs7 = b64decode(response.json()['mozilla.rsa'])

    cert_serial_num = get_signer_serial_number(pkcs7)

    # We only want the (unique) temporary file name.
    with tempfile.NamedTemporaryFile(dir=settings.TMP_PATH) as temp_file:
        temp_filename = temp_file.name

    jar.make_signed(
        signed_manifest=signed_manifest,
        signature=pkcs7,
        sigpath=u'mozilla',
        outpath=temp_filename)
    shutil.move(temp_filename, file_obj.file_path)
    return cert_serial_num