@@ -970,7 +970,7 @@ def from_der(cls, string, hashfunc=sha1):
970970
971971 if algorithm_oid not in (oid_ecPublicKey , oid_ecDH , oid_ecMQV ):
972972 raise der .UnexpectedDER (
973- "unexpected algorithm identifier '%s'" % algorithm_oid
973+ "unexpected algorithm identifier '%s'" % ( algorithm_oid ,)
974974 )
975975 if empty != b"" :
976976 raise der .UnexpectedDER (
@@ -1049,7 +1049,7 @@ def to_string(self):
10491049 s = number_to_string (secexp , self .privkey .order )
10501050 return s
10511051
1052- def to_pem (self , point_encoding = "uncompressed" ):
1052+ def to_pem (self , point_encoding = "uncompressed" , format = "sslay" ):
10531053 """
10541054 Convert the private key to the :term:`PEM` format.
10551055
@@ -1058,9 +1058,11 @@ def to_pem(self, point_encoding="uncompressed"):
10581058 Only the named curve format is supported.
10591059 The public key will be included in generated string.
10601060
1061- The PEM header will specify ``BEGIN EC PRIVATE KEY``
1061+ The PEM header will specify ``BEGIN EC PRIVATE KEY`` or
1062+ ``BEGIN PRIVATE KEY``, depending on the desired format.
10621063
10631064 :param str point_encoding: format to use for encoding public point
1065+ :param str format: either `sslay` or `pkcs8`
10641066
10651067 :return: PEM encoded private key
10661068 :rtype: bytes
@@ -1069,9 +1071,11 @@ def to_pem(self, point_encoding="uncompressed"):
10691071 re-encoded if the system is incompatible (e.g. uses UTF-16)
10701072 """
10711073 # TODO: "BEGIN ECPARAMETERS"
1072- return der .topem (self .to_der (point_encoding ), "EC PRIVATE KEY" )
1074+ assert format in ("sslay" , "pkcs8" )
1075+ header = "EC PRIVATE KEY" if format == "sslay" else "PRIVATE KEY"
1076+ return der .topem (self .to_der (point_encoding , format ), header )
10731077
1074- def to_der (self , point_encoding = "uncompressed" ):
1078+ def to_der (self , point_encoding = "uncompressed" , format = "sslay" ):
10751079 """
10761080 Convert the private key to the :term:`DER` format.
10771081
@@ -1081,6 +1085,7 @@ def to_der(self, point_encoding="uncompressed"):
10811085 The public key will be included in the generated string.
10821086
10831087 :param str point_encoding: format to use for encoding public point
1088+ :param str format: either `sslay` or `pkcs8`
10841089
10851090 :return: DER encoded private key
10861091 :rtype: bytes
@@ -1089,16 +1094,30 @@ def to_der(self, point_encoding="uncompressed"):
10891094 # cont[1],bitstring])
10901095 if point_encoding == "raw" :
10911096 raise ValueError ("raw encoding not allowed in DER" )
1097+ assert format in ("sslay" , "pkcs8" )
10921098 encoded_vk = self .get_verifying_key ().to_string (point_encoding )
10931099 # the 0 in encode_bitstring specifies the number of unused bits
10941100 # in the `encoded_vk` string
1095- return der .encode_sequence (
1101+ ec_private_key = der .encode_sequence (
10961102 der .encode_integer (1 ),
10971103 der .encode_octet_string (self .to_string ()),
10981104 der .encode_constructed (0 , self .curve .encoded_oid ),
10991105 der .encode_constructed (1 , der .encode_bitstring (encoded_vk , 0 )),
11001106 )
11011107
1108+ if format == "sslay" :
1109+ return ec_private_key
1110+ else :
1111+ return der .encode_sequence (
1112+ # version = 1 means the public key is not present in the
1113+ # top-level structure.
1114+ der .encode_integer (1 ),
1115+ der .encode_sequence (
1116+ der .encode_oid (* oid_ecPublicKey ), self .curve .encoded_oid
1117+ ),
1118+ der .encode_octet_string (ec_private_key ),
1119+ )
1120+
11021121 def get_verifying_key (self ):
11031122 """
11041123 Return the VerifyingKey associated with this private key.
0 commit comments