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")
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()
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()
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)
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)
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)
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)
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
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()
def from_der(cls, der, context=GLOBAL_CONTEXT): return PrivateKey(int_to_bytes_padded(PrivateKeyInfo.load(der).native['private_key']['private_key']), context)
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 )
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")