Beispiel #1
0
    def test_rc4_128_encrypt_decrypt(self):
        key = util.rand_bytes(16)
        data = b'This is data to encrypt'

        ciphertext = symmetric.rc4_encrypt(key, data)
        self.assertNotEqual(data, ciphertext)
        self.assertEqual(byte_cls, type(ciphertext))

        plaintext = symmetric.rc4_decrypt(key, ciphertext)
        self.assertEqual(data, plaintext)
Beispiel #2
0
    def test_rc4_128_encrypt_decrypt(self):
        key = util.rand_bytes(16)
        data = b'This is data to encrypt'

        ciphertext = symmetric.rc4_encrypt(key, data)
        self.assertNotEqual(data, ciphertext)
        self.assertEqual(byte_cls, type(ciphertext))

        plaintext = symmetric.rc4_decrypt(key, ciphertext)
        self.assertEqual(data, plaintext)
Beispiel #3
0
    def test_3des_2k_encrypt_decrypt(self):
        key = util.rand_bytes(16)
        data = b'This is data to encrypt'

        iv, ciphertext = symmetric.tripledes_cbc_pkcs5_encrypt(key, data, None)
        self.assertNotEqual(data, ciphertext)
        self.assertEqual(byte_cls, type(ciphertext))

        plaintext = symmetric.tripledes_cbc_pkcs5_decrypt(key, ciphertext, iv)
        self.assertEqual(data, plaintext)
Beispiel #4
0
    def test_3des_2k_encrypt_decrypt(self):
        key = util.rand_bytes(16)
        data = b'This is data to encrypt'

        iv, ciphertext = symmetric.tripledes_cbc_pkcs5_encrypt(key, data, None)
        self.assertNotEqual(data, ciphertext)
        self.assertEqual(byte_cls, type(ciphertext))

        plaintext = symmetric.tripledes_cbc_pkcs5_decrypt(key, ciphertext, iv)
        self.assertEqual(data, plaintext)
Beispiel #5
0
def counter(counts):
    zaehler = counts
    e = {'kopf': 0, 'zahl': 0}
    while range(zaehler != 0):
        rnd = util.rand_bytes(1)
        rnd = int.from_bytes(rnd, byteorder='little')
        if rnd >= (255 / 2):
            e['zahl'] = e.get("zahl") + 1
        else:
            e['kopf'] = e.get("kopf") + 1
        zaehler = zaehler - 1
    return e
Beispiel #6
0
async def manual_translate_async(request):
    x = await handle_post(request)
    if isinstance(x, tuple):
        img, size, selected_translator, target_language, detector, direction = x
    else:
        return x
    task_id = crypto_utils.rand_bytes(16).hex()
    print(f'New `manual-translate` task {task_id}')
    os.makedirs(f'result/{task_id}/', exist_ok=True)
    img.save(f'result/{task_id}/input.png')
    QUEUE.append(task_id)
    TASK_DATA[task_id] = {
        'size': size,
        'manual': True,
        'detector': detector,
        'direction': direction,
        'created_at': time.time()
    }
    TASK_STATES[task_id] = 'pending'
    while True:
        await asyncio.sleep(1)
        if 'trans_request' in TASK_DATA[task_id]:
            return web.json_response({
                'task_id':
                task_id,
                'status':
                'pending',
                'trans_result':
                TASK_DATA[task_id]['trans_request']
            })
        if TASK_STATES[task_id] in ['error', 'error-lang']:
            break
        if TASK_STATES[task_id] == 'finished':
            # no texts detected
            return web.json_response({
                'task_id': task_id,
                'status': 'successful'
            })
    return web.json_response({'task_id': task_id, 'status': 'failed'})
Beispiel #7
0
async def main(mode='demo'):
    print(' -- Loading models')
    os.makedirs('result', exist_ok=True)
    text_render.prepare_renderer()
    with open('alphabet-all-v5.txt', 'r', encoding='utf-8') as fp:
        dictionary = [s[:-1] for s in fp.readlines()]
    load_ocr_model(dictionary, args.use_cuda)
    from textblockdetector import load_model as load_ctd_model
    load_ctd_model(args.use_cuda)
    load_detection_model(args.use_cuda)
    load_inpainting_model(args.use_cuda)

    if mode == 'demo':
        print(' -- Running in single image demo mode')
        if not args.image:
            print('please provide an image')
            parser.print_usage()
            return
        img, alpha_ch = convert_img(Image.open(args.image))
        img = np.array(img)
        await infer(img, mode, '', alpha_ch=alpha_ch)
    elif mode == 'web':
        print(' -- Running in web service mode')
        print(' -- Waiting for translation tasks')
        nonce = crypto_utils.rand_bytes(16).hex()
        import subprocess
        import sys
        subprocess.Popen([sys.executable, 'web_main.py', nonce, '5003'])
        while True:
            task_id, options = get_task(nonce)
            if task_id:
                print(f' -- Processing task {task_id}')
                img, alpha_ch = convert_img(
                    Image.open(f'result/{task_id}/input.png'))
                img = np.array(img)
                try:
                    infer_task = asyncio.create_task(
                        infer_safe(img,
                                   mode,
                                   nonce,
                                   options,
                                   task_id,
                                   alpha_ch=alpha_ch))
                    asyncio.gather(infer_task)
                except:
                    import traceback
                    traceback.print_exc()
                    update_state(task_id, nonce, 'error')
            else:
                await asyncio.sleep(0.1)
    elif mode == 'web2':
        print(' -- Running in web service mode')
        print(' -- Waiting for translation tasks')
        while True:
            task_id, options = get_task(nonce)
            if task_id:
                print(f' -- Processing task {task_id}')
                img, alpha_ch = convert_img(
                    Image.open(f'result/{task_id}/input.png'))
                img = np.array(img)
                try:
                    infer_task = asyncio.create_task(
                        infer_safe(img,
                                   mode,
                                   nonce,
                                   options,
                                   task_id,
                                   alpha_ch=alpha_ch))
                    asyncio.gather(infer_task)
                except:
                    import traceback
                    traceback.print_exc()
                    update_state(task_id, nonce, 'error')
            else:
                await asyncio.sleep(0.1)
    elif mode == 'batch':
        src = os.path.abspath(args.image)
        if src[-1] == '\\' or src[-1] == '/':
            src = src[:-1]
        dst = args.image_dst or src + '-translated'
        if os.path.exists(dst) and not os.path.isdir(dst):
            print(
                f'Destination `{dst}` already exists and is not a directory! Please specify another directory.'
            )
            return
        if os.path.exists(dst) and os.listdir(dst):
            print(
                f'Destination directory `{dst}` already exists! Please specify another directory.'
            )
            return
        print('Processing image in source directory')
        files = []
        for root, subdirs, files in os.walk(src):
            dst_root = replace_prefix(root, src, dst)
            os.makedirs(dst_root, exist_ok=True)
            for f in files:
                if f.lower() == '.thumb':
                    continue
                filename = os.path.join(root, f)
                try:
                    img, alpha_ch = convert_img(Image.open(filename))
                    img = np.array(img)
                    if img is None:
                        continue
                except Exception:
                    pass
                try:
                    dst_filename = replace_prefix(filename, src, dst)
                    print('Processing', filename, '->', dst_filename)
                    await infer(img,
                                'demo',
                                '',
                                dst_image_name=dst_filename,
                                alpha_ch=alpha_ch)
                except Exception:
                    import traceback
                    traceback.print_exc()
                    pass
Beispiel #8
0
 def __init__(self, salted_key, iv=None):
     self.salted_key = salted_key[
         :32
     ]  # this implementation supports only (256 bits) // 8 = 32 bytes.
     self.iv = iv if iv is not None else crypt_util.rand_bytes(self.IV_LENGTH)
Beispiel #9
0
def generate_app_key():
    """
    Generate a random str of bytes for the app_key
    """
    return crypt_util.rand_bytes(32)
Beispiel #10
0
def generate_salt():
    return crypt_util.rand_bytes(256)
Beispiel #11
0
def encrypt_message(data_to_encrypt, enc_alg, encryption_cert):
    """Function encrypts data and returns the generated ASN.1

    :param data_to_encrypt: A byte string of the data to be encrypted
    
    :param enc_alg: The algorithm to be used for encrypting the data
    
    :param encryption_cert: The certificate to be used for encrypting the data

    :return: A CMS ASN.1 byte string of the encrypted data.    
    """

    enc_alg_list = enc_alg.split('_')
    cipher, key_length, mode = enc_alg_list[0], enc_alg_list[1], enc_alg_list[
        2]
    enc_alg_asn1, encrypted_content = None, None

    # Generate the symmetric encryption key and encrypt the message
    key = util.rand_bytes(int(key_length) // 8)
    if cipher == 'tripledes':
        algorithm_id = '1.2.840.113549.3.7'
        iv, encrypted_content = symmetric.tripledes_cbc_pkcs5_encrypt(
            key, data_to_encrypt, None)
        enc_alg_asn1 = algos.EncryptionAlgorithm({
            'algorithm':
            algorithm_id,
            'parameters':
            cms.OctetString(iv)
        })

    elif cipher == 'rc2':
        algorithm_id = '1.2.840.113549.3.2'
        iv, encrypted_content = symmetric.rc2_cbc_pkcs5_encrypt(
            key, data_to_encrypt, None)
        enc_alg_asn1 = algos.EncryptionAlgorithm({
            'algorithm':
            algorithm_id,
            'parameters':
            algos.Rc2Params({'iv': cms.OctetString(iv)})
        })

    elif cipher == 'rc4':
        algorithm_id = '1.2.840.113549.3.4'
        encrypted_content = symmetric.rc4_encrypt(key, data_to_encrypt)
        enc_alg_asn1 = algos.EncryptionAlgorithm({
            'algorithm': algorithm_id,
        })

    elif cipher == 'aes':
        if key_length == '128':
            algorithm_id = '2.16.840.1.101.3.4.1.2'
        elif key_length == '192':
            algorithm_id = '2.16.840.1.101.3.4.1.22'
        else:
            algorithm_id = '2.16.840.1.101.3.4.1.42'

        iv, encrypted_content = symmetric.aes_cbc_pkcs7_encrypt(
            key, data_to_encrypt, None)
        enc_alg_asn1 = algos.EncryptionAlgorithm({
            'algorithm':
            algorithm_id,
            'parameters':
            cms.OctetString(iv)
        })

    # Encrypt the key and build the ASN.1 message
    encrypted_key = asymmetric.rsa_pkcs1v15_encrypt(encryption_cert, key)

    return cms.ContentInfo({
        'content_type':
        cms.ContentType('enveloped_data'),
        'content':
        cms.EnvelopedData({
            'version':
            cms.CMSVersion('v0'),
            'recipient_infos': [
                cms.KeyTransRecipientInfo({
                    'version':
                    cms.CMSVersion('v0'),
                    'rid':
                    cms.RecipientIdentifier({
                        'issuer_and_serial_number':
                        cms.IssuerAndSerialNumber({
                            'issuer':
                            encryption_cert.asn1['tbs_certificate']['issuer'],
                            'serial_number':
                            encryption_cert.asn1['tbs_certificate']
                            ['serial_number']
                        })
                    }),
                    'key_encryption_algorithm':
                    cms.KeyEncryptionAlgorithm(
                        {'algorithm': cms.KeyEncryptionAlgorithmId('rsa')}),
                    'encrypted_key':
                    cms.OctetString(encrypted_key)
                })
            ],
            'encrypted_content_info':
            cms.EncryptedContentInfo({
                'content_type': cms.ContentType('data'),
                'content_encryption_algorithm': enc_alg_asn1,
                'encrypted_content': encrypted_content
            })
        })
    }).dump()
Beispiel #12
0
def encrypt_message(data_to_encrypt, enc_alg, encryption_cert):
    """Function encrypts data and returns the generated ASN.1

    :param data_to_encrypt: A byte string of the data to be encrypted
    :param enc_alg: The algorithm to be used for encrypting the data
    :param encryption_cert: The certificate to be used for encrypting the data

    :return: A CMS ASN.1 byte string of the encrypted data.
    """

    enc_alg_list = enc_alg.split("_")
    cipher, key_length, _ = enc_alg_list[0], enc_alg_list[1], enc_alg_list[2]

    # Generate the symmetric encryption key and encrypt the message
    key = util.rand_bytes(int(key_length) // 8)
    if cipher == "tripledes":
        algorithm_id = "1.2.840.113549.3.7"
        iv, encrypted_content = symmetric.tripledes_cbc_pkcs5_encrypt(
            key, data_to_encrypt, None)
        enc_alg_asn1 = algos.EncryptionAlgorithm({
            "algorithm":
            algorithm_id,
            "parameters":
            cms.OctetString(iv)
        })

    elif cipher == "rc2":
        algorithm_id = "1.2.840.113549.3.2"
        iv, encrypted_content = symmetric.rc2_cbc_pkcs5_encrypt(
            key, data_to_encrypt, None)
        enc_alg_asn1 = algos.EncryptionAlgorithm({
            "algorithm":
            algorithm_id,
            "parameters":
            algos.Rc2Params({"iv": cms.OctetString(iv)}),
        })

    elif cipher == "rc4":
        algorithm_id = "1.2.840.113549.3.4"
        encrypted_content = symmetric.rc4_encrypt(key, data_to_encrypt)
        enc_alg_asn1 = algos.EncryptionAlgorithm({
            "algorithm": algorithm_id,
        })

    elif cipher == "aes":
        if key_length == "128":
            algorithm_id = "2.16.840.1.101.3.4.1.2"
        elif key_length == "192":
            algorithm_id = "2.16.840.1.101.3.4.1.22"
        else:
            algorithm_id = "2.16.840.1.101.3.4.1.42"

        iv, encrypted_content = symmetric.aes_cbc_pkcs7_encrypt(
            key, data_to_encrypt, None)
        enc_alg_asn1 = algos.EncryptionAlgorithm({
            "algorithm":
            algorithm_id,
            "parameters":
            cms.OctetString(iv)
        })
    elif cipher == "des":
        algorithm_id = "1.3.14.3.2.7"
        iv, encrypted_content = symmetric.des_cbc_pkcs5_encrypt(
            key, data_to_encrypt, None)
        enc_alg_asn1 = algos.EncryptionAlgorithm({
            "algorithm":
            algorithm_id,
            "parameters":
            cms.OctetString(iv)
        })
    else:
        raise AS2Exception("Unsupported Encryption Algorithm")

    # Encrypt the key and build the ASN.1 message
    encrypted_key = asymmetric.rsa_pkcs1v15_encrypt(encryption_cert, key)

    return cms.ContentInfo({
        "content_type":
        cms.ContentType("enveloped_data"),
        "content":
        cms.EnvelopedData({
            "version":
            cms.CMSVersion("v0"),
            "recipient_infos": [
                cms.KeyTransRecipientInfo({
                    "version":
                    cms.CMSVersion("v0"),
                    "rid":
                    cms.RecipientIdentifier({
                        "issuer_and_serial_number":
                        cms.IssuerAndSerialNumber({
                            "issuer":
                            encryption_cert.asn1["tbs_certificate"]["issuer"],
                            "serial_number":
                            encryption_cert.asn1["tbs_certificate"]
                            ["serial_number"],
                        })
                    }),
                    "key_encryption_algorithm":
                    cms.KeyEncryptionAlgorithm(
                        {"algorithm": cms.KeyEncryptionAlgorithmId("rsa")}),
                    "encrypted_key":
                    cms.OctetString(encrypted_key),
                })
            ],
            "encrypted_content_info":
            cms.EncryptedContentInfo({
                "content_type": cms.ContentType("data"),
                "content_encryption_algorithm": enc_alg_asn1,
                "encrypted_content": encrypted_content,
            }),
        }),
    }).dump()
Beispiel #13
0
    def build_mpc(self, signing_private_key, orq_ip, orq_port):
        """
        Validates the certificate information, constructs the ASN.1 structure
        and then signs it with a mpc engine

        :param signing_private_key:
            An integer identifier for the private key to sign the certificate with.
            This identifier permits the mpc engine to find the private key associated
            with the public key exported in the key generation process

        :return:
            An asn1crypto.x509.Certificate object of the newly signed
            certificate
        """
        def rsa_mpc_sign(signing_private_key, tbs_cert_dump, hash_algo, orq_ip,
                         orq_port):

            # Calculate hash corresponding to tbs_cert_dump	[Only SHA256]
            digest = hashes.Hash(hashes.SHA256(), backend=default_backend())
            digest.update(tbs_cert_dump)
            digest = hexlify(digest.finalize())
            print("[Client] Hash: " + digest)

            # Send HTTP GET request to the orquestrator for signing
            target = "http://" + orq_ip + ":" + orq_port + "/signMessage/" + str(
                signing_private_key) + "?message=" + str(digest)
            r = requests.get(target)

            response = dict(json.loads(r.text))

            # Sign format must be bytearray
            print("Firma: " + str(response["sign"]))
            firma = unhexlify(response["sign"])
            return firma

        if self._self_signed is not True and self._issuer is None:
            raise ValueError(
                _pretty_message('''
                Certificate must be self-signed, or an issuer must be specified
                '''))

        if self._self_signed:
            self._issuer = self._subject

        if self._serial_number is None:
            time_part = int_to_bytes(int(time.time()))
            random_part = util.rand_bytes(4)
            self._serial_number = int_from_bytes(time_part + random_part)

        if self._begin_date is None:
            self._begin_date = datetime.now(timezone.utc)

        if self._end_date is None:
            self._end_date = self._begin_date + timedelta(365)

        if not self.ca:
            for ca_only_extension in set([
                    'policy_mappings', 'policy_constraints',
                    'inhibit_any_policy'
            ]):
                if ca_only_extension in self._other_extensions:
                    raise ValueError(
                        _pretty_message(
                            '''
                        Extension %s is only valid for CA certificates
                        ''', ca_only_extension))

        # The algorith is forced to be 'rsa'
        signature_algo = 'rsa'

        # Hash's algorithm limited to SHA256 (internally)
        signature_algorithm_id = '%s_%s' % (self._hash_algo, signature_algo)

        def _make_extension(name, value):
            return {
                'extn_id': name,
                'critical': self._determine_critical(name),
                'extn_value': value
            }

        extensions = []
        for name in sorted(self._special_extensions):
            value = getattr(self, '_%s' % name)
            if name == 'ocsp_no_check':
                value = core.Null() if value else None
            if value is not None:
                extensions.append(_make_extension(name, value))

        for name in sorted(self._other_extensions.keys()):
            extensions.append(
                _make_extension(name, self._other_extensions[name]))

        tbs_cert = x509.TbsCertificate({
            'version': 'v3',
            'serial_number': self._serial_number,
            'signature': {
                'algorithm': signature_algorithm_id
            },
            'issuer': self._issuer,
            'validity': {
                'not_before': x509.Time(name='utc_time',
                                        value=self._begin_date),
                'not_after': x509.Time(name='utc_time', value=self._end_date),
            },
            'subject': self._subject,
            'subject_public_key_info': self._subject_public_key,
            'extensions': extensions
        })

        # Function binding
        sign_func = rsa_mpc_sign
        print(orq_ip)
        print(orq_port)
        signature = sign_func(signing_private_key, tbs_cert.dump(),
                              self._hash_algo, orq_ip, orq_port)

        return x509.Certificate({
            'tbs_certificate': tbs_cert,
            'signature_algorithm': {
                'algorithm': signature_algorithm_id
            },
            'signature_value': signature
        })
Beispiel #14
0
    def build(self, requestor_private_key=None, requestor_certificate=None, other_certificates=None):
        """
        Validates the request information, constructs the ASN.1 structure and
        then optionally signs it.

        The requestor_private_key, requestor_certificate and other_certificates
        params are all optional and only necessary if the request needs to be
        signed. Signing a request is uncommon for OCSP requests related to web
        TLS connections.

        :param requestor_private_key:
            An asn1crypto.keys.PrivateKeyInfo or oscrypto.asymmetric.PrivateKey
            object for the private key to sign the request with

        :param requestor_certificate:
            An asn1crypto.x509.Certificate or oscrypto.asymmetric.Certificate
            object of the certificate associated with the private key

        :param other_certificates:
            A list of asn1crypto.x509.Certificate or
            oscrypto.asymmetric.Certificate objects that may be useful for the
            OCSP server to verify the request signature. Intermediate
            certificates would be specified here.

        :return:
            An asn1crypto.ocsp.OCSPRequest object of the request
        """

        def _make_extension(name, value):
            return {
                'extn_id': name,
                'critical': False,
                'extn_value': value
            }

        tbs_request_extensions = []
        request_extensions = []
        has_nonce = False

        for name, value in self._tbs_request_extensions.items():
            if name == 'nonce':
                has_nonce = True
            tbs_request_extensions.append(_make_extension(name, value))
        if self._nonce and not has_nonce:
            tbs_request_extensions.append(
                _make_extension('nonce', util.rand_bytes(16))
            )

        if not tbs_request_extensions:
            tbs_request_extensions = None

        for name, value in self._request_extensions.items():
            request_extensions.append(_make_extension(name, value))

        if not request_extensions:
            request_extensions = None

        tbs_request = ocsp.TBSRequest({
            'request_list': [
                {
                    'req_cert': {
                        'hash_algorithm': {
                            'algorithm': self._key_hash_algo
                        },
                        'issuer_name_hash': getattr(self._certificate.issuer, self._key_hash_algo),
                        'issuer_key_hash': getattr(self._issuer.public_key, self._key_hash_algo),
                        'serial_number': self._certificate.serial_number,
                    },
                    'single_request_extensions': request_extensions
                }
            ],
            'request_extensions': tbs_request_extensions
        })
        signature = None

        if requestor_private_key or requestor_certificate or other_certificates:
            is_oscrypto = isinstance(requestor_private_key, asymmetric.PrivateKey)
            if not isinstance(requestor_private_key, keys.PrivateKeyInfo) and not is_oscrypto:
                raise TypeError(_pretty_message(
                    '''
                    requestor_private_key must be an instance of
                    asn1crypto.keys.PrivateKeyInfo or
                    oscrypto.asymmetric.PrivateKey, not %s
                    ''',
                    _type_name(requestor_private_key)
                ))

            cert_is_oscrypto = isinstance(requestor_certificate, asymmetric.Certificate)
            if not isinstance(requestor_certificate, x509.Certificate) and not cert_is_oscrypto:
                raise TypeError(_pretty_message(
                    '''
                    requestor_certificate must be an instance of
                    asn1crypto.x509.Certificate or
                    oscrypto.asymmetric.Certificate, not %s
                    ''',
                    _type_name(requestor_certificate)
                ))

            if other_certificates is not None and not isinstance(other_certificates, list):
                raise TypeError(_pretty_message(
                    '''
                    other_certificates must be a list of
                    asn1crypto.x509.Certificate or
                    oscrypto.asymmetric.Certificate objects, not %s
                    ''',
                    _type_name(other_certificates)
                ))

            if cert_is_oscrypto:
                requestor_certificate = requestor_certificate.asn1

            tbs_request['requestor_name'] = x509.GeneralName(
                name='directory_name',
                value=requestor_certificate.subject
            )

            certificates = [requestor_certificate]

            for other_certificate in other_certificates:
                other_cert_is_oscrypto = isinstance(other_certificate, asymmetric.Certificate)
                if not isinstance(other_certificate, x509.Certificate) and not other_cert_is_oscrypto:
                    raise TypeError(_pretty_message(
                        '''
                        other_certificate must be an instance of
                        asn1crypto.x509.Certificate or
                        oscrypto.asymmetric.Certificate, not %s
                        ''',
                        _type_name(other_certificate)
                    ))
                if other_cert_is_oscrypto:
                    other_certificate = other_certificate.asn1
                certificates.append(other_certificate)

            signature_algo = requestor_private_key.algorithm
            if signature_algo == 'ec':
                signature_algo = 'ecdsa'

            signature_algorithm_id = '%s_%s' % (self._hash_algo, signature_algo)

            if requestor_private_key.algorithm == 'rsa':
                sign_func = asymmetric.rsa_pkcs1v15_sign
            elif requestor_private_key.algorithm == 'dsa':
                sign_func = asymmetric.dsa_sign
            elif requestor_private_key.algorithm == 'ec':
                sign_func = asymmetric.ecdsa_sign

            if not is_oscrypto:
                requestor_private_key = asymmetric.load_private_key(requestor_private_key)
            signature_bytes = sign_func(requestor_private_key, tbs_request.dump(), self._hash_algo)

            signature = ocsp.Signature({
                'signature_algorithm': {'algorithm': signature_algorithm_id},
                'signature': signature_bytes,
                'certs': certificates
            })

        return ocsp.OCSPRequest({
            'tbs_request': tbs_request,
            'optional_signature': signature
        })
Beispiel #15
0
    def build(self, signing_private_key):
        """
        Validates the certificate information, constructs the ASN.1 structure
        and then signs it

        :param signing_private_key:
            An asn1crypto.keys.PrivateKeyInfo or oscrypto.asymmetric.PrivateKey
            object for the private key to sign the certificate with. If the key
            is self-signed, this should be the private key that matches the
            public key, otherwise it needs to be the issuer's private key.

        :return:
            An asn1crypto.x509.Certificate object of the newly signed
            certificate
        """

        is_oscrypto = isinstance(signing_private_key, asymmetric.PrivateKey)
        if not isinstance(
                signing_private_key, keys.PrivateKeyInfo
        ) and not is_oscrypto and signing_private_key is not None:
            raise TypeError(
                _pretty_message(
                    '''
                signing_private_key must be an instance of
                asn1crypto.keys.PrivateKeyInfo or
                oscrypto.asymmetric.PrivateKey, not %s
                ''', _type_name(signing_private_key)))

        if self._self_signed is not True and self._issuer is None:
            raise ValueError(
                _pretty_message('''
                Certificate must be self-signed, or an issuer must be specified
                '''))

        if self._self_signed:
            self._issuer = self._subject

        if self._serial_number is None:
            time_part = int_to_bytes(int(time.time()))
            random_part = util.rand_bytes(4)
            self._serial_number = int_from_bytes(time_part + random_part)

        if self._begin_date is None:
            self._begin_date = datetime.now(timezone.utc)

        if self._end_date is None:
            self._end_date = self._begin_date + timedelta(365)

        if not self.ca:
            for ca_only_extension in set([
                    'policy_mappings', 'policy_constraints',
                    'inhibit_any_policy'
            ]):
                if ca_only_extension in self._other_extensions:
                    raise ValueError(
                        _pretty_message(
                            '''
                        Extension %s is only valid for CA certificates
                        ''', ca_only_extension))

        if signing_private_key is not None:
            signature_algo = signing_private_key.algorithm
            if signature_algo == 'ec':
                signature_algo = 'ecdsa'

            signature_algorithm_id = '%s_%s' % (self._hash_algo,
                                                signature_algo)
        else:
            signature_algorithm_id = '%s_%s' % (
                self._hash_algo, "rsa")  #making rsa assumption for ease

        # RFC 3280 4.1.2.5
        def _make_validity_time(dt):
            if dt < datetime(2050, 1, 1, tzinfo=timezone.utc):
                value = x509.Time(name='utc_time', value=dt)
            else:
                value = x509.Time(name='general_time', value=dt)

            return value

        def _make_extension(name, value):
            return {
                'extn_id': name,
                'critical': self._determine_critical(name),
                'extn_value': value
            }

        extensions = []
        for name in sorted(self._special_extensions):
            value = getattr(self, '_%s' % name)
            if name == 'ocsp_no_check':
                value = core.Null() if value else None
            if value is not None:
                extensions.append(_make_extension(name, value))

        for name in sorted(self._other_extensions.keys()):
            extensions.append(
                _make_extension(name, self._other_extensions[name]))

        tbs_cert = x509.TbsCertificate({
            'version': 'v3',
            'serial_number': self._serial_number,
            'signature': {
                'algorithm': signature_algorithm_id
            },
            'issuer': self._issuer,
            'validity': {
                'not_before': _make_validity_time(self._begin_date),
                'not_after': _make_validity_time(self._end_date),
            },
            'subject': self._subject,
            'subject_public_key_info': self._subject_public_key,
            'extensions': extensions
        })

        if signing_private_key is None:
            return tbs_cert
        elif signing_private_key.algorithm == 'rsa':
            sign_func = asymmetric.rsa_pkcs1v15_sign
        elif signing_private_key.algorithm == 'dsa':
            sign_func = asymmetric.dsa_sign
        elif signing_private_key.algorithm == 'ec':
            sign_func = asymmetric.ecdsa_sign

        if not is_oscrypto:
            signing_private_key = asymmetric.load_private_key(
                signing_private_key)
        signature = sign_func(signing_private_key, tbs_cert.dump(),
                              self._hash_algo)

        return x509.Certificate({
            'tbs_certificate': tbs_cert,
            'signature_algorithm': {
                'algorithm': signature_algorithm_id
            },
            'signature_value': signature
        })
Beispiel #16
0
    def build(self,
              requestor_private_key=None,
              requestor_certificate=None,
              other_certificates=None):
        """
        Validates the request information, constructs the ASN.1 structure and
        then optionally signs it.

        The requestor_private_key, requestor_certificate and other_certificates
        params are all optional and only necessary if the request needs to be
        signed. Signing a request is uncommon for OCSP requests related to web
        TLS connections.

        :param requestor_private_key:
            An asn1crypto.keys.PrivateKeyInfo or oscrypto.asymmetric.PrivateKey
            object for the private key to sign the request with

        :param requestor_certificate:
            An asn1crypto.x509.Certificate or oscrypto.asymmetric.Certificate
            object of the certificate associated with the private key

        :param other_certificates:
            A list of asn1crypto.x509.Certificate or
            oscrypto.asymmetric.Certificate objects that may be useful for the
            OCSP server to verify the request signature. Intermediate
            certificates would be specified here.

        :return:
            An asn1crypto.ocsp.OCSPRequest object of the request
        """
        def _make_extension(name, value):
            return {'extn_id': name, 'critical': False, 'extn_value': value}

        tbs_request_extensions = []
        request_extensions = []
        has_nonce = False

        for name, value in self._tbs_request_extensions.items():
            if name == 'nonce':
                has_nonce = True
            tbs_request_extensions.append(_make_extension(name, value))
        if self._nonce and not has_nonce:
            tbs_request_extensions.append(
                _make_extension('nonce', util.rand_bytes(16)))

        if not tbs_request_extensions:
            tbs_request_extensions = None

        for name, value in self._request_extensions.items():
            request_extensions.append(_make_extension(name, value))

        if not request_extensions:
            request_extensions = None

        tbs_request = ocsp.TBSRequest({
            'request_list': [{
                'req_cert': {
                    'hash_algorithm': {
                        'algorithm': self._key_hash_algo
                    },
                    'issuer_name_hash':
                    getattr(cert.issuer, self._key_hash_algo),
                    'issuer_key_hash':
                    getattr(self._issuer.public_key, self._key_hash_algo),
                    'serial_number':
                    cert.serial_number,
                },
                'single_request_extensions': request_extensions
            } for cert in self._certificates],
            'request_extensions':
            tbs_request_extensions
        })
        signature = None

        if requestor_private_key or requestor_certificate or other_certificates:
            is_oscrypto = isinstance(requestor_private_key,
                                     asymmetric.PrivateKey)
            if not isinstance(requestor_private_key,
                              keys.PrivateKeyInfo) and not is_oscrypto:
                raise TypeError(
                    _pretty_message(
                        '''
                    requestor_private_key must be an instance of
                    asn1crypto.keys.PrivateKeyInfo or
                    oscrypto.asymmetric.PrivateKey, not %s
                    ''', _type_name(requestor_private_key)))

            cert_is_oscrypto = isinstance(requestor_certificate,
                                          asymmetric.Certificate)
            if not isinstance(requestor_certificate,
                              x509.Certificate) and not cert_is_oscrypto:
                raise TypeError(
                    _pretty_message(
                        '''
                    requestor_certificate must be an instance of
                    asn1crypto.x509.Certificate or
                    oscrypto.asymmetric.Certificate, not %s
                    ''', _type_name(requestor_certificate)))

            if other_certificates is not None and not isinstance(
                    other_certificates, list):
                raise TypeError(
                    _pretty_message(
                        '''
                    other_certificates must be a list of
                    asn1crypto.x509.Certificate or
                    oscrypto.asymmetric.Certificate objects, not %s
                    ''', _type_name(other_certificates)))

            if cert_is_oscrypto:
                requestor_certificate = requestor_certificate.asn1

            tbs_request['requestor_name'] = x509.GeneralName(
                name='directory_name', value=requestor_certificate.subject)

            certificates = [requestor_certificate]

            for other_certificate in other_certificates:
                other_cert_is_oscrypto = isinstance(other_certificate,
                                                    asymmetric.Certificate)
                if not isinstance(
                        other_certificate,
                        x509.Certificate) and not other_cert_is_oscrypto:
                    raise TypeError(
                        _pretty_message(
                            '''
                        other_certificate must be an instance of
                        asn1crypto.x509.Certificate or
                        oscrypto.asymmetric.Certificate, not %s
                        ''', _type_name(other_certificate)))
                if other_cert_is_oscrypto:
                    other_certificate = other_certificate.asn1
                certificates.append(other_certificate)

            signature_algo = requestor_private_key.algorithm
            if signature_algo == 'ec':
                signature_algo = 'ecdsa'

            signature_algorithm_id = '%s_%s' % (self._hash_algo,
                                                signature_algo)

            if requestor_private_key.algorithm == 'rsa':
                sign_func = asymmetric.rsa_pkcs1v15_sign
            elif requestor_private_key.algorithm == 'dsa':
                sign_func = asymmetric.dsa_sign
            elif requestor_private_key.algorithm == 'ec':
                sign_func = asymmetric.ecdsa_sign

            if not is_oscrypto:
                requestor_private_key = asymmetric.load_private_key(
                    requestor_private_key)
            signature_bytes = sign_func(requestor_private_key,
                                        tbs_request.dump(), self._hash_algo)

            signature = ocsp.Signature({
                'signature_algorithm': {
                    'algorithm': signature_algorithm_id
                },
                'signature': signature_bytes,
                'certs': certificates
            })

        return ocsp.OCSPRequest({
            'tbs_request': tbs_request,
            'optional_signature': signature
        })
Beispiel #17
0
    def build(self, signing_private_key):
        """
        Validates the certificate information, constructs the ASN.1 structure
        and then signs it

        :param signing_private_key:
            An asn1crypto.keys.PrivateKeyInfo or oscrypto.asymmetric.PrivateKey
            object for the private key to sign the certificate with. If the key
            is self-signed, this should be the private key that matches the
            public key, otherwise it needs to be the issuer's private key.

        :return:
            An asn1crypto.x509.Certificate object of the newly signed
            certificate
        """

        is_oscrypto = isinstance(signing_private_key, asymmetric.PrivateKey)
        if not isinstance(signing_private_key, keys.PrivateKeyInfo) and not is_oscrypto:
            raise TypeError(_pretty_message(
                '''
                signing_private_key must be an instance of
                asn1crypto.keys.PrivateKeyInfo or
                oscrypto.asymmetric.PrivateKey, not %s
                ''',
                _type_name(signing_private_key)
            ))

        if self._self_signed is not True and self._issuer is None:
            raise ValueError(_pretty_message(
                '''
                Certificate must be self-signed, or an issuer must be specified
                '''
            ))

        if self._self_signed:
            self._issuer = self._subject

        if self._serial_number is None:
            time_part = int_to_bytes(int(time.time()))
            random_part = util.rand_bytes(4)
            self._serial_number = int_from_bytes(time_part + random_part)

        if self._begin_date is None:
            self._begin_date = datetime.now(timezone.utc)

        if self._end_date is None:
            self._end_date = self._begin_date + timedelta(365)

        if not self.ca:
            for ca_only_extension in set(['policy_mappings', 'policy_constraints', 'inhibit_any_policy']):
                if ca_only_extension in self._other_extensions:
                    raise ValueError(_pretty_message(
                        '''
                        Extension %s is only valid for CA certificates
                        ''',
                        ca_only_extension
                    ))

        signature_algo = signing_private_key.algorithm
        if signature_algo == 'ec':
            signature_algo = 'ecdsa'

        signature_algorithm_id = '%s_%s' % (self._hash_algo, signature_algo)

        # RFC 3280 4.1.2.5
        def _make_validity_time(dt):
            if dt < datetime(2050, 1, 1, tzinfo=timezone.utc):
                value = x509.Time(name='utc_time', value=dt)
            else:
                value = x509.Time(name='general_time', value=dt)

            return value

        def _make_extension(name, value):
            return {
                'extn_id': name,
                'critical': self._determine_critical(name),
                'extn_value': value
            }

        extensions = []
        for name in sorted(self._special_extensions):
            value = getattr(self, '_%s' % name)
            if name == 'ocsp_no_check':
                value = core.Null() if value else None
            if value is not None:
                extensions.append(_make_extension(name, value))

        for name in sorted(self._other_extensions.keys()):
            extensions.append(_make_extension(name, self._other_extensions[name]))

        tbs_cert = x509.TbsCertificate({
            'version': 'v3',
            'serial_number': self._serial_number,
            'signature': {
                'algorithm': signature_algorithm_id
            },
            'issuer': self._issuer,
            'validity': {
                'not_before': _make_validity_time(self._begin_date),
                'not_after': _make_validity_time(self._end_date),
            },
            'subject': self._subject,
            'subject_public_key_info': self._subject_public_key,
            'extensions': extensions
        })

        if signing_private_key.algorithm == 'rsa':
            sign_func = asymmetric.rsa_pkcs1v15_sign
        elif signing_private_key.algorithm == 'dsa':
            sign_func = asymmetric.dsa_sign
        elif signing_private_key.algorithm == 'ec':
            sign_func = asymmetric.ecdsa_sign

        if not is_oscrypto:
            signing_private_key = asymmetric.load_private_key(signing_private_key)
        signature = sign_func(signing_private_key, tbs_cert.dump(), self._hash_algo)

        return x509.Certificate({
            'tbs_certificate': tbs_cert,
            'signature_algorithm': {
                'algorithm': signature_algorithm_id
            },
            'signature_value': signature
        })
Beispiel #18
0
    def build(self,
              requestor_private_key=None,
              requestor_certificate=None,
              other_certificates=None):
        def _make_extension(name, value):
            return {'extn_id': name, 'critical': False, 'extn_value': value}

        tbs_request_extensions = []
        request_extensions = []
        has_nonce = False

        for name, value in self._tbs_request_extensions.items():
            if name == 'nonce':
                has_nonce = True
            tbs_request_extensions.append(_make_extension(name, value))
        if self._nonce and not has_nonce:
            tbs_request_extensions.append(
                _make_extension('nonce', util.rand_bytes(16)))

        if not tbs_request_extensions:
            tbs_request_extensions = None

        for name, value in self._request_extensions.items():
            request_extensions.append(_make_extension(name, value))

        if not request_extensions:
            request_extensions = None

        tbs_request = ocsp.TBSRequest({
            'request_list': [{
                'req_cert': {
                    'hash_algorithm': {
                        'algorithm': self._key_hash_algo
                    },
                    'issuer_name_hash':
                    getattr(self._certificate.issuer, self._key_hash_algo),
                    'issuer_key_hash':
                    getattr(self._issuer.public_key, self._key_hash_algo),
                    'serial_number':
                    self._certificate.serial_number,
                },
                'single_request_extensions': request_extensions
            }],
            'request_extensions':
            tbs_request_extensions
        })
        signature = None

        if requestor_private_key or requestor_certificate or other_certificates:
            is_oscrypto = isinstance(requestor_private_key,
                                     asymmetric.PrivateKey)
            if not isinstance(requestor_private_key,
                              keys.PrivateKeyInfo) and not is_oscrypto:
                raise TypeError(
                    _pretty_message(
                        '''
                    requestor_private_key must be an instance of
                    asn1crypto.keys.PrivateKeyInfo or
                    oscrypto.asymmetric.PrivateKey, not %s
                    ''', _type_name(requestor_private_key)))

            cert_is_oscrypto = isinstance(requestor_certificate,
                                          asymmetric.Certificate)
            if not isinstance(requestor_certificate,
                              x509.Certificate) and not cert_is_oscrypto:
                raise TypeError(
                    _pretty_message(
                        '''
                    requestor_certificate must be an instance of
                    asn1crypto.x509.Certificate or
                    oscrypto.asymmetric.Certificate, not %s
                    ''', _type_name(requestor_certificate)))

            if other_certificates is not None and not isinstance(
                    other_certificates, list):
                raise TypeError(
                    _pretty_message(
                        '''
                    other_certificates must be a list of
                    asn1crypto.x509.Certificate or
                    oscrypto.asymmetric.Certificate objects, not %s
                    ''', _type_name(other_certificates)))

            if cert_is_oscrypto:
                requestor_certificate = requestor_certificate.asn1

            tbs_request['requestor_name'] = x509.GeneralName(
                name='directory_name', value=requestor_certificate.subject)

            certificates = [requestor_certificate]

            for other_certificate in other_certificates:
                other_cert_is_oscrypto = isinstance(other_certificate,
                                                    asymmetric.Certificate)
                if not isinstance(
                        other_certificate,
                        x509.Certificate) and not other_cert_is_oscrypto:
                    raise TypeError(
                        _pretty_message(
                            '''
                        other_certificate must be an instance of
                        asn1crypto.x509.Certificate or
                        oscrypto.asymmetric.Certificate, not %s
                        ''', _type_name(other_certificate)))
                if other_cert_is_oscrypto:
                    other_certificate = other_certificate.asn1
                certificates.append(other_certificate)

            signature_algo = requestor_private_key.algorithm
            if signature_algo == 'ec':
                signature_algo = 'ecdsa'

            signature_algorithm_id = '%s_%s' % (self._hash_algo,
                                                signature_algo)

            if requestor_private_key.algorithm == 'rsa':
                sign_func = asymmetric.rsa_pkcs1v15_sign
            elif requestor_private_key.algorithm == 'dsa':
                sign_func = asymmetric.dsa_sign
            elif requestor_private_key.algorithm == 'ec':
                sign_func = asymmetric.ecdsa_sign

            if not is_oscrypto:
                requestor_private_key = asymmetric.load_private_key(
                    requestor_private_key)
            signature_bytes = sign_func(requestor_private_key,
                                        tbs_request.dump(), self._hash_algo)

            signature = ocsp.Signature({
                'signature_algorithm': {
                    'algorithm': signature_algorithm_id
                },
                'signature': signature_bytes,
                'certs': certificates
            })

        return ocsp.OCSPRequest({
            'tbs_request': tbs_request,
            'optional_signature': signature
        })