@@ -848,8 +848,8 @@ def from_pem(cls, string, hashfunc=sha1):
848848 Initialise from key stored in :term:`PEM` format.
849849
850850 The PEM formats supported are the un-encrypted RFC5915
851- (the sslay format) supported by OpenSSL, and the more common RFC5958
852- (the PKCS #8 format).
851+ (the sslay format) supported by OpenSSL, and the more common
852+ un-encrypted RFC5958 (the PKCS #8 format).
853853
854854 The legacy format files have the header with the string
855855 ``BEGIN EC PRIVATE KEY``.
@@ -876,30 +876,23 @@ def from_pem(cls, string, hashfunc=sha1):
876876 if not PY2 and isinstance (string , str ):
877877 string = string .encode ()
878878
879- # the privkey pem may have multiple sections, commonly it also has
880- # "EC PARAMETERS", we need just "EC PRIVATE KEY".
881- ec_private_key_index = string .find (b"-----BEGIN EC PRIVATE KEY-----" )
882- if ec_private_key_index != - 1 :
883- return cls .from_der (
884- der .unpem (string [ec_private_key_index :]), hashfunc , pkcs8 = False
885- )
886-
887- private_key_index = string .find (b"-----BEGIN PRIVATE KEY-----" )
888- if private_key_index != - 1 :
889- return cls .from_der (
890- der .unpem (string [private_key_index :]), hashfunc , pkcs8 = True
891- )
879+ # The privkey pem may have multiple sections, commonly it also has
880+ # "EC PARAMETERS", we need just "EC PRIVATE KEY". PKCS#8 should not
881+ # have the "EC PARAMETERS" section; it's just "PRIVATE KEY".
882+ private_key_index = string .find (b"-----BEGIN EC PRIVATE KEY-----" )
883+ if private_key_index == - 1 :
884+ private_key_index = string .index (b"-----BEGIN PRIVATE KEY-----" )
892885
893- raise ValueError ( "No EC PRIVATE KEY or PRIVATE KEY section in PEM" )
886+ return cls . from_der ( der . unpem ( string [ private_key_index :]), hashfunc )
894887
895888 @classmethod
896- def from_der (cls , string , hashfunc = sha1 , pkcs8 = False ):
889+ def from_der (cls , string , hashfunc = sha1 ):
897890 """
898891 Initialise from key stored in :term:`DER` format.
899892
900893 The DER formats supported are the un-encrypted RFC5915
901- (the sslay format) supported by OpenSSL, and the more common RFC5958
902- (the PKCS #8 format).
894+ (the sslay format) supported by OpenSSL, and the more common
895+ un-encrypted RFC5958 (the PKCS #8 format).
903896
904897 Both formats contain an ASN.1 object following the syntax specified
905898 in RFC5915::
@@ -911,10 +904,14 @@ def from_der(cls, string, hashfunc=sha1, pkcs8=False):
911904 publicKey [1] BIT STRING OPTIONAL
912905 }
913906
907+ `publicKey` field is ignored completely (errors, if any, in it will
908+ be undetected).
909+
914910 The only format supported for the `parameters` field is the named
915911 curve method. Explicit encoding of curve parameters is not supported.
916912 In the legacy sslay format, this implementation requires the optional
917- `parameters` field to get the curve name.
913+ `parameters` field to get the curve name. In PKCS #8 format, the curve
914+ is part of the PrivateKeyAlgorithmIdentifier.
918915
919916 The PKCS #8 format includes this object as the `privateKey` field
920917 within a larger structure:
@@ -929,15 +926,12 @@ def from_der(cls, string, hashfunc=sha1, pkcs8=False):
929926 ...
930927 }
931928
932- `publicKey` field is ignored completely (errors, if any, in it will
933- be undetected) .
929+ The `attributes` and `publicKey` fields are completely ignored; errors
930+ in them will not be detected .
934931
935932 :param string: binary string with DER-encoded private ECDSA key
936933 :type string: bytes like object
937934
938- :param pkcs8: whether to expect the data in PKCS #8 format
939- :type pkcs8: boolean
940-
941935 :raises MalformedPointError: if the length of encoding doesn't match
942936 the provided curve or the encoded values is too large
943937 :raises RuntimeError: if the generation of public key from private
@@ -950,28 +944,27 @@ def from_der(cls, string, hashfunc=sha1, pkcs8=False):
950944 s = normalise_bytes (string )
951945 curve = None
952946
953- # PKCS #8 has the algorithm identifier, including the curve name,
954- # before the actual key. Then it contains the key data within an
955- # octet string.
956- if pkcs8 :
957- s , empty = der .remove_sequence (s )
958- if empty != b ("" ):
959- raise der .UnexpectedDER (
960- "trailing junk after DER privkey: %s"
961- % binascii .hexlify (empty )
962- )
947+ s , empty = der .remove_sequence (s )
948+ if empty != b ("" ):
949+ raise der .UnexpectedDER (
950+ "trailing junk after DER privkey: %s" % binascii .hexlify (empty )
951+ )
963952
964- version , s = der .remove_integer (s )
965- if version != 0 and version != 1 :
953+ version , s = der .remove_integer (s )
954+
955+ # At this point, PKCS #8 has a sequence containing the algorithm
956+ # identifier and the curve identifier. The sslay format instead has
957+ # an octet string containing the key data, so this is how we can
958+ # distinguish the two formats.
959+ if der .is_sequence (s ):
960+ if version not in (0 , 1 ):
966961 raise der .UnexpectedDER (
967- "expected '0' or '1' at start of DER privkey, got %d"
962+ "expected version '0' or '1' at start of privkey, got %d"
968963 % version
969964 )
970965
971- algorithm_identifier , s = der .remove_sequence (s )
972- algorithm_oid , algorithm_identifier = der .remove_object (
973- algorithm_identifier
974- )
966+ sequence , s = der .remove_sequence (s )
967+ algorithm_oid , algorithm_identifier = der .remove_object (sequence )
975968 curve_oid , empty = der .remove_object (algorithm_identifier )
976969 curve = find_curve (curve_oid )
977970
@@ -985,19 +978,28 @@ def from_der(cls, string, hashfunc=sha1, pkcs8=False):
985978 % binascii .hexlify (empty )
986979 )
987980
988- # We don't care about the optional fields after the key data.
981+ # Up next is an octet string containing an ECPrivateKey. Ignore
982+ # the optional "attributes" and "publicKey" fields that come after.
989983 s , _ = der .remove_octet_string (s )
990984
991- s , empty = der .remove_sequence (s )
992- if empty != b ("" ):
993- raise der .UnexpectedDER (
994- "trailing junk after DER privkey: %s" % binascii .hexlify (empty )
995- )
996- one , s = der .remove_integer (s )
997- if one != 1 :
985+ # Unpack the ECPrivateKey to get to the key data octet string,
986+ # and rejoin the sslay parsing path.
987+ s , empty = der .remove_sequence (s )
988+ if empty != b ("" ):
989+ raise der .UnexpectedDER (
990+ "trailing junk after DER privkey: %s"
991+ % binascii .hexlify (empty )
992+ )
993+
994+ version , s = der .remove_integer (s )
995+
996+ # The version of the ECPrivateKey must be 1.
997+ if version != 1 :
998998 raise der .UnexpectedDER (
999- "expected '1' at start of DER privkey, got %d" % one
999+ "expected version '1' at start of DER privkey, got %d"
1000+ % version
10001001 )
1002+
10011003 privkey_str , s = der .remove_octet_string (s )
10021004
10031005 if not curve :
0 commit comments