def test_load() -> None:
    # not RSA
    with pytest.raises(ValueError):
        TextbookRsaPrivateKey.load(b"""
-----BEGIN PRIVATE KEY-----
MIGHAgEAMBMGByqGSM49AgEGCCqGSM49AwEHBG0wawIBAQQgCaUaXQQho8ZJzBxW
GAUaaZYXpCrAIkTGQ4SNFPgc8a6hRANCAARuhfAJsHe80Rqp5wI4IxhM8QDk5CgV
eQcGofFqXjiWpch0OAKBQTbCqdvAnmXzG2rqfA4sJNwGIIi6xXfZxQEn
-----END PRIVATE KEY-----
        """)

    key_der = b64decode("".join(key_pem.strip().splitlines()[1:-1]))
    pki = PrivateKeyInfo.load(key_der)
    k0 = TextbookRsaPrivateKey.load(pki)
    k1 = TextbookRsaPrivateKey.load(key_pem)
    k2 = TextbookRsaPrivateKey.load(key_der)

    assert k0.private_exponent == key.private_exponent
    assert k1.private_exponent == key.private_exponent
    assert k2.private_exponent == key.private_exponent

    # public exponent is encoded as "00 01 00 01", i.e. bad leading zero.
    with pytest.raises(ValueError):
        TextbookRsaPrivateKey.load(
            b64decode("""
MIIBVQIBADANBgkqhkiG9w0BAQEFAASCAT8wggE7AgEAAkEA6cwdAA4K/x7+sHX5TS+rNtM/v3hDr+sdQr3Bbl0JCwKH
yiWpVKt6fsKFCfsBD/Zvfe++Ot+GAAe/M2r2mN660QIEAAEAAQJAfERjfa35JlVBJmXuVppptMBf99NiltSvPtRBRfnp
XpG7j6JFwAsAyKcsAFo4ZXMj3K71GLLVRXKNVArRSuwj4QIhAPwAaunIMWjw/wWA/I0vIqKf/i18DFe0Pv8q+SM54Ipl
AiEA7YHA0rpJLQ6JIGHG/ZL9F8GKXtFf6sjlszYzBli8Uf0CIQDlFZgbiELqjFK49SYhTp0ky18siB1MSW4PV0h+rmmi
RQIgExHN9515bqKyI+V14rpAk/24LHDHMMS8nK0HX8UUKckCIENRTBNmauD1vtBqstLj456t712kYvV3MFunRbc6hR7C
        """))

    with pytest.raises(TypeError):
        TextbookRsaPrivateKey.load("Hello")
Пример #2
0
    def to_der(self) -> bytes:
        """
        :return: The private key encoded in DER format.
        """
        pk = ECPrivateKey({
            'version':
            'ecPrivkeyVer1',
            'private_key':
            self.to_int(),
            'public_key':
            ECPointBitString(self.public_key.format(compressed=False)),
        })

        return PrivateKeyInfo({
            'version':
            0,
            'private_key_algorithm':
            PrivateKeyAlgorithm({
                'algorithm':
                'ec',
                'parameters':
                ECDomainParameters(name='named', value='1.3.132.0.10'),
            }),
            'private_key':
            pk,
        }).dump()
Пример #3
0
def apply_sig(filename: str, detach_path: str):
    """
    Attach the signature for the bundle of the same name at the detach_path
    """
    bundle, filepath = get_bundle_exec(filename)
    detach_bundle = os.path.join(detach_path, os.path.basename(bundle))

    bin_code_signers: Dict[str, CodeSigner] = {}

    for file_path in glob.iglob(os.path.join(detach_bundle, "**"),
                                recursive=True):
        if os.path.isdir(file_path):
            continue
        bundle_relpath = os.path.relpath(file_path, detach_bundle)
        bundle_path = os.path.join(bundle, bundle_relpath)

        if os.path.basename(os.path.dirname(file_path)) == "MacOS":
            # Signature files are only in the MacOS dir
            if file_path.endswith("sign"):
                bin_name, ext = os.path.splitext(file_path)

                bundle_relpath = os.path.relpath(bin_name, detach_bundle)
                bundle_path = os.path.join(bundle, bundle_relpath)

                if bin_name not in bin_code_signers:
                    bin_code_signers[bin_name] = CodeSigner(
                        bundle_path, Certificate(), PrivateKeyInfo())
                bcs = bin_code_signers[bin_name]

                # Figure out which index this sig is for
                idx = 0
                macho = bcs.macho
                if hasattr(bcs.macho, "Fhdr"):
                    if ext == ".sign":
                        raise Exception(
                            "Cannot attach single architecture signature to universal binary"
                        )
                    arch_type = CPU_NAME_TO_TYPE[ext[1:-4]]
                    for i, h in enumerate(bcs.macho.fh):
                        if h.cputype == arch_type:
                            idx = i
                            macho = bcs.macho.arch[i]
                            break

                # Create a CodeSignatureAttacher
                csa = CodeSignatureAttacher(bundle_path, idx, macho, file_path)

                # Add it to the CodeSigner
                bcs.code_signers.append(csa)

                continue

        # Non-signature files are just copied over
        os.makedirs(os.path.dirname(bundle_path), exist_ok=True)
        shutil.copyfile(file_path, bundle_path)

    # Apply the signature for all CodeSigners
    for _, cs in bin_code_signers.items():
        cs.apply_signature()
Пример #4
0
 def from_pem(cls, ledger, pem) -> 'PrivateKey':
     der = pem_to_der(pem.encode())
     try:
         key_int = ECPrivateKey.load(der).native['private_key']
     except ValueError:
         key_int = PrivateKeyInfo.load(der).native['private_key']['private_key']
     private_key = cPrivateKey.from_int(key_int)
     return cls(ledger, private_key, bytes((0,)*32), 0, 0)
Пример #5
0
 def from_der(cls, der: bytes, context: Context = GLOBAL_CONTEXT):
     """
     :param der: The private key encoded in DER format.
     :param context:
     :return: The private key.
     :rtype: PrivateKey
     """
     return PrivateKey(
         int_to_bytes_padded(
             PrivateKeyInfo.load(der).native['private_key']['private_key']),
         context)
Пример #6
0
def _sign_pss_raw(data: bytes, signing_key: keys.PrivateKeyInfo,
                  params: algos.RSASSAPSSParams, digest_algorithm: str):

    pss_padding, hash_algo = _process_pss_params(params, digest_algorithm)

    from cryptography.hazmat.primitives import serialization
    from cryptography.hazmat.primitives.asymmetric.rsa import RSAPrivateKey
    priv_key: RSAPrivateKey = serialization.load_der_private_key(
        signing_key.dump(), password=None)

    return priv_key.sign(data=data, padding=pss_padding, algorithm=hash_algo)
Пример #7
0
 def from_pem(cls, pem: bytes, context: Context = GLOBAL_CONTEXT):
     """
     :param pem: The private key encoded in PEM format.
     :param context:
     :return: The private key.
     :rtype: PrivateKey
     """
     return PrivateKey(
         int_to_bytes_padded(
             PrivateKeyInfo.load(
                 pem_to_der(pem)).native['private_key']['private_key']),
         context)
Пример #8
0
def _oscrypto_hacky_load_pss_exclusive_key(private: keys.PrivateKeyInfo):
    from oscrypto import asymmetric
    # HACK to load PSS-exclusive RSA keys in oscrypto
    #  Don't ever do this in production code!
    algo_copy = private['private_key_algorithm'].native
    private_copy = keys.PrivateKeyInfo.load(private.dump())
    # set the algorithm to "generic RSA"
    private_copy['private_key_algorithm'] = {'algorithm': 'rsa'}
    loaded_key = asymmetric.load_private_key(private_copy)
    public = loaded_key.public_key.asn1
    public['algorithm'] = algo_copy
    return loaded_key, public
Пример #9
0
    def to_der(self):
        pk = ECPrivateKey(
            {
                'version': ensure_unicode('ecPrivkeyVer1'),
                'private_key': self.to_int(),
                'public_key': ECPointBitString(self.public_key.format(compressed=False)),
            }
        )

        return PrivateKeyInfo(
            {
                'version': 0,
                'private_key_algorithm': PrivateKeyAlgorithm(
                    {
                        'algorithm': ensure_unicode('ec'),
                        'parameters': ECDomainParameters(name='named', value=ensure_unicode('1.3.132.0.10')),
                    }
                ),
                'private_key': pk,
            }
        ).dump()
Пример #10
0
 def from_der(cls, der, context=GLOBAL_CONTEXT):
     return PrivateKey(int_to_bytes_padded(PrivateKeyInfo.load(der).native['private_key']['private_key']), context)
Пример #11
0
 def from_pem(cls, pem, context=GLOBAL_CONTEXT):
     return PrivateKey(
         int_to_bytes_padded(PrivateKeyInfo.load(pem_to_der(pem)).native['private_key']['private_key']), context
     )
Пример #12
0
def generic_sign_prehashed(private_key: keys.PrivateKeyInfo, tbs_digest: bytes,
                           sd_algo: algos.SignedDigestAlgorithm,
                           digest_algorithm) -> bytes:
    from cryptography.hazmat.primitives import hashes, serialization
    from cryptography.hazmat.primitives.asymmetric import dsa, ec, padding, rsa
    from cryptography.hazmat.primitives.asymmetric.utils import Prehashed

    if private_key.algorithm == 'rsassa_pss':
        # as usual, we need to pretend it's a normal RSA key
        # for pyca_cryptography to be able to load it
        private_key_copy = private_key.copy()
        private_key_copy['private_key_algorithm'] = {'algorithm': 'rsa'}
        priv_key_bytes = private_key_copy.dump()
    else:
        priv_key_bytes = private_key.dump()

    priv_key = serialization.load_der_private_key(priv_key_bytes,
                                                  password=None)
    sig_algo = sd_algo.signature_algo
    if sig_algo == 'rsassa_pkcs1v15':
        padding: padding.AsymmetricPadding = padding.PKCS1v15()
        hash_algo = getattr(hashes, digest_algorithm.upper())()
        assert isinstance(priv_key, rsa.RSAPrivateKey)
        return priv_key.sign(tbs_digest, padding, Prehashed(hash_algo))
    elif sig_algo == 'rsassa_pss':
        parameters = None
        if private_key.algorithm == 'rsassa_pss':
            key_params = \
                private_key['private_key_algorithm']['parameters']
            # if the key is parameterised, we must use those params
            if key_params.native is not None:
                parameters = key_params
        if parameters is None:
            parameters = sd_algo['parameters']

        mga: algos.MaskGenAlgorithm = parameters['mask_gen_algorithm']
        if not mga['algorithm'].native == 'mgf1':
            raise NotImplementedError("Only MFG1 is supported")

        mgf_md_name = mga['parameters']['algorithm'].native

        salt_len: int = parameters['salt_length'].native

        mgf_md = getattr(hashes, mgf_md_name.upper())()
        pss_padding: padding.AsymmetricPadding = padding.PSS(
            mgf=padding.MGF1(algorithm=mgf_md), salt_length=salt_len)
        hash_algo = getattr(hashes, digest_algorithm.upper())()
        assert isinstance(priv_key, rsa.RSAPrivateKey)
        return priv_key.sign(tbs_digest, pss_padding, Prehashed(hash_algo))
    elif sig_algo == 'dsa':
        assert isinstance(priv_key, dsa.DSAPrivateKey)
        hash_algo = getattr(hashes, digest_algorithm.upper())()
        return priv_key.sign(tbs_digest, Prehashed(hash_algo))
    elif sig_algo == 'ecdsa':
        hash_algo = getattr(hashes, digest_algorithm.upper())()
        assert isinstance(priv_key, ec.EllipticCurvePrivateKey)
        return priv_key.sign(tbs_digest,
                             signature_algorithm=ec.ECDSA(
                                 Prehashed(hash_algo)))
    else:  # pragma: nocover
        raise NotImplementedError(f"The signature signature_algo {sig_algo} "
                                  f"is unsupported")