aboutsummaryrefslogtreecommitdiff
path: root/frozen_deps/Cryptodome/IO/PKCS8.py
diff options
context:
space:
mode:
Diffstat (limited to 'frozen_deps/Cryptodome/IO/PKCS8.py')
-rw-r--r--frozen_deps/Cryptodome/IO/PKCS8.py111
1 files changed, 53 insertions, 58 deletions
diff --git a/frozen_deps/Cryptodome/IO/PKCS8.py b/frozen_deps/Cryptodome/IO/PKCS8.py
index 7365476..3041545 100644
--- a/frozen_deps/Cryptodome/IO/PKCS8.py
+++ b/frozen_deps/Cryptodome/IO/PKCS8.py
@@ -48,53 +48,39 @@ __all__ = ['wrap', 'unwrap']
def wrap(private_key, key_oid, passphrase=None, protection=None,
- prot_params=None, key_params=None, randfunc=None):
+ prot_params=None, key_params=DerNull(), randfunc=None):
"""Wrap a private key into a PKCS#8 blob (clear or encrypted).
Args:
- private_key (byte string):
+ private_key (bytes):
The private key encoded in binary form. The actual encoding is
algorithm specific. In most cases, it is DER.
key_oid (string):
The object identifier (OID) of the private key to wrap.
- It is a dotted string, like ``1.2.840.113549.1.1.1`` (for RSA keys).
+ It is a dotted string, like ``'1.2.840.113549.1.1.1'`` (for RSA keys)
+ or ``'1.2.840.10045.2.1'`` (for ECC keys).
- passphrase (bytes string or string):
+ Keyword Args:
+
+ passphrase (bytes or string):
The secret passphrase from which the wrapping key is derived.
Set it only if encryption is required.
protection (string):
The identifier of the algorithm to use for securely wrapping the key.
- The default value is ``PBKDF2WithHMAC-SHA1AndDES-EDE3-CBC``.
+ Refer to :ref:`the encryption parameters<enc_params>` .
+ The default value is ``'PBKDF2WithHMAC-SHA1AndDES-EDE3-CBC'``.
prot_params (dictionary):
- Parameters for the protection algorithm.
-
- +------------------+-----------------------------------------------+
- | Key | Description |
- +==================+===============================================+
- | iteration_count | The KDF algorithm is repeated several times to|
- | | slow down brute force attacks on passwords |
- | | (called *N* or CPU/memory cost in scrypt). |
- | | The default value for PBKDF2 is 1000. |
- | | The default value for scrypt is 16384. |
- +------------------+-----------------------------------------------+
- | salt_size | Salt is used to thwart dictionary and rainbow |
- | | attacks on passwords. The default value is 8 |
- | | bytes. |
- +------------------+-----------------------------------------------+
- | block_size | *(scrypt only)* Memory-cost (r). The default |
- | | value is 8. |
- +------------------+-----------------------------------------------+
- | parallelization | *(scrypt only)* CPU-cost (p). The default |
- | | value is 1. |
- +------------------+-----------------------------------------------+
-
- key_params (DER object):
- The algorithm parameters associated to the private key.
- It is required for algorithms like DSA, but not for others like RSA.
+ Parameters for the key derivation function (KDF).
+ Refer to :ref:`the encryption parameters<enc_params>` .
+
+ key_params (DER object or None):
+ The ``parameters`` field to use in the ``AlgorithmIdentifier``
+ SEQUENCE. If ``None``, no ``parameters`` field will be added.
+ By default, the ASN.1 type ``NULL`` is used.
randfunc (callable):
Random number generation function; it should accept a single integer
@@ -102,13 +88,10 @@ def wrap(private_key, key_oid, passphrase=None, protection=None,
If not specified, a new RNG will be instantiated
from :mod:`Cryptodome.Random`.
- Return:
- The PKCS#8-wrapped private key (possibly encrypted), as a byte string.
+ Returns:
+ bytes: The PKCS#8-wrapped private key (possibly encrypted).
"""
- if key_params is None:
- key_params = DerNull()
-
#
# PrivateKeyInfo ::= SEQUENCE {
# version Version,
@@ -117,12 +100,14 @@ def wrap(private_key, key_oid, passphrase=None, protection=None,
# attributes [0] IMPLICIT Attributes OPTIONAL
# }
#
+ if key_params is None:
+ algorithm = DerSequence([DerObjectId(key_oid)])
+ else:
+ algorithm = DerSequence([DerObjectId(key_oid), key_params])
+
pk_info = DerSequence([
0,
- DerSequence([
- DerObjectId(key_oid),
- key_params
- ]),
+ algorithm,
DerOctetString(private_key)
])
pk_info_der = pk_info.encode()
@@ -145,8 +130,10 @@ def unwrap(p8_private_key, passphrase=None):
"""Unwrap a private key from a PKCS#8 blob (clear or encrypted).
Args:
- p8_private_key (byte string):
- The private key wrapped into a PKCS#8 blob, DER encoded.
+ p8_private_key (bytes):
+ The private key wrapped into a PKCS#8 container, DER encoded.
+
+ Keyword Args:
passphrase (byte string or string):
The passphrase to use to decrypt the blob (if it is encrypted).
@@ -154,8 +141,8 @@ def unwrap(p8_private_key, passphrase=None):
A tuple containing
#. the algorithm identifier of the wrapped key (OID, dotted string)
- #. the private key (byte string, DER encoded)
- #. the associated parameters (byte string, DER encoded) or ``None``
+ #. the private key (bytes, DER encoded)
+ #. the associated parameters (bytes, DER encoded) or ``None``
Raises:
ValueError : if decoding fails
@@ -185,11 +172,12 @@ def unwrap(p8_private_key, passphrase=None):
if not found:
raise ValueError("Error decoding PKCS#8 (%s)" % error_str)
- pk_info = DerSequence().decode(p8_private_key, nr_elements=(2, 3, 4))
+ pk_info = DerSequence().decode(p8_private_key, nr_elements=(2, 3, 4, 5))
if len(pk_info) == 2 and not passphrase:
raise ValueError("Not a valid clear PKCS#8 structure "
"(maybe it is encrypted?)")
+ # RFC5208, PKCS#8, version is v1(0)
#
# PrivateKeyInfo ::= SEQUENCE {
# version Version,
@@ -197,22 +185,27 @@ def unwrap(p8_private_key, passphrase=None):
# privateKey PrivateKey,
# attributes [0] IMPLICIT Attributes OPTIONAL
# }
- # Version ::= INTEGER
- if pk_info[0] != 0:
- raise ValueError("Not a valid PrivateKeyInfo SEQUENCE")
-
- # PrivateKeyAlgorithmIdentifier ::= AlgorithmIdentifier
#
- # EncryptedPrivateKeyInfo ::= SEQUENCE {
- # encryptionAlgorithm EncryptionAlgorithmIdentifier,
- # encryptedData EncryptedData
+ # RFC5915, Asymmetric Key Package, version is v2(1)
+ #
+ # OneAsymmetricKey ::= SEQUENCE {
+ # version Version,
+ # privateKeyAlgorithm PrivateKeyAlgorithmIdentifier,
+ # privateKey PrivateKey,
+ # attributes [0] Attributes OPTIONAL,
+ # ...,
+ # [[2: publicKey [1] PublicKey OPTIONAL ]],
+ # ...
# }
- # EncryptionAlgorithmIdentifier ::= AlgorithmIdentifier
- # AlgorithmIdentifier ::= SEQUENCE {
- # algorithm OBJECT IDENTIFIER,
- # parameters ANY DEFINED BY algorithm OPTIONAL
- # }
+ if pk_info[0] == 0:
+ if len(pk_info) not in (3, 4):
+ raise ValueError("Not a valid PrivateKeyInfo SEQUENCE")
+ elif pk_info[0] == 1:
+ if len(pk_info) not in (3, 4, 5):
+ raise ValueError("Not a valid PrivateKeyInfo SEQUENCE")
+ else:
+ raise ValueError("Not a valid PrivateKeyInfo SEQUENCE")
algo = DerSequence().decode(pk_info[1], nr_elements=(1, 2))
algo_oid = DerObjectId().decode(algo[0]).value
@@ -225,7 +218,9 @@ def unwrap(p8_private_key, passphrase=None):
except:
algo_params = algo[1]
- # EncryptedData ::= OCTET STRING
+ # PrivateKey ::= OCTET STRING
private_key = DerOctetString().decode(pk_info[2]).payload
+ # We ignore attributes and (for v2 only) publickey
+
return (algo_oid, private_key, algo_params)