From a88b8c8c0f591a3bfa8d7984343a27815184f495 Mon Sep 17 00:00:00 2001 From: "Jeremy T. Bouse" Date: Sun, 29 May 2011 08:16:54 -0400 Subject: Imported Upstream version 1.7.7.1 --- docs/paramiko.pkey-pysrc.html | 724 +++++++++++++++++++++--------------------- 1 file changed, 363 insertions(+), 361 deletions(-) (limited to 'docs/paramiko.pkey-pysrc.html') diff --git a/docs/paramiko.pkey-pysrc.html b/docs/paramiko.pkey-pysrc.html index ef16bb0..56f0c4b 100644 --- a/docs/paramiko.pkey-pysrc.html +++ b/docs/paramiko.pkey-pysrc.html @@ -81,7 +81,7 @@ 25 import os 26 27 from Crypto.Hash import MD5 - 28 from Crypto.Cipher import DES3 + 28 from Crypto.Cipher import DES3, AES 29 30 from paramiko.common import * 31 from paramiko import util @@ -96,244 +96,245 @@ 40 41 # known encryption types for private key files: 42 _CIPHER_TABLE = { - 43 'DES-EDE3-CBC': { 'cipher': DES3, 'keysize': 24, 'blocksize': 8, 'mode': DES3.MODE_CBC } - 44 } - 45 + 43 'AES-128-CBC': { 'cipher': AES, 'keysize': 16, 'blocksize': 16, 'mode': AES.MODE_CBC }, + 44 'DES-EDE3-CBC': { 'cipher': DES3, 'keysize': 24, 'blocksize': 8, 'mode': DES3.MODE_CBC }, + 45 } 46 -
47 - def __init__(self, msg=None, data=None): -
48 """ - 49 Create a new instance of this public key type. If C{msg} is given, - 50 the key's public part(s) will be filled in from the message. If - 51 C{data} is given, the key's public part(s) will be filled in from - 52 the string. - 53 - 54 @param msg: an optional SSH L{Message} containing a public key of this - 55 type. - 56 @type msg: L{Message} - 57 @param data: an optional string containing a public key of this type - 58 @type data: str - 59 - 60 @raise SSHException: if a key cannot be created from the C{data} or - 61 C{msg} given, or no key was passed in. - 62 """ - 63 pass -
64 -
65 - def __str__(self): -
66 """ - 67 Return a string of an SSH L{Message} made up of the public part(s) of - 68 this key. This string is suitable for passing to L{__init__} to - 69 re-create the key object later. - 70 - 71 @return: string representation of an SSH key message. - 72 @rtype: str - 73 """ - 74 return '' -
75 -
76 - def __cmp__(self, other): -
77 """ - 78 Compare this key to another. Returns 0 if this key is equivalent to - 79 the given key, or non-0 if they are different. Only the public parts - 80 of the key are compared, so a public key will compare equal to its - 81 corresponding private key. - 82 - 83 @param other: key to compare to. - 84 @type other: L{PKey} - 85 @return: 0 if the two keys are equivalent, non-0 otherwise. - 86 @rtype: int - 87 """ - 88 hs = hash(self) - 89 ho = hash(other) - 90 if hs != ho: - 91 return cmp(hs, ho) - 92 return cmp(str(self), str(other)) -
93 -
94 - def get_name(self): -
95 """ - 96 Return the name of this private key implementation. - 97 - 98 @return: name of this private key type, in SSH terminology (for - 99 example, C{"ssh-rsa"}). -100 @rtype: str -101 """ -102 return '' -
103 -
104 - def get_bits(self): -
105 """ -106 Return the number of significant bits in this key. This is useful -107 for judging the relative security of a key. -108 -109 @return: bits in the key. -110 @rtype: int -111 """ -112 return 0 -
113 -
114 - def can_sign(self): -
115 """ -116 Return C{True} if this key has the private part necessary for signing -117 data. -118 -119 @return: C{True} if this is a private key. -120 @rtype: bool -121 """ -122 return False -
123 -
124 - def get_fingerprint(self): -
125 """ -126 Return an MD5 fingerprint of the public part of this key. Nothing -127 secret is revealed. -128 -129 @return: a 16-byte string (binary) of the MD5 fingerprint, in SSH -130 format. -131 @rtype: str -132 """ -133 return MD5.new(str(self)).digest() -
134 -
135 - def get_base64(self): -
136 """ -137 Return a base64 string containing the public part of this key. Nothing -138 secret is revealed. This format is compatible with that used to store -139 public key files or recognized host keys. -140 -141 @return: a base64 string containing the public part of the key. -142 @rtype: str -143 """ -144 return base64.encodestring(str(self)).replace('\n', '') -
145 -
146 - def sign_ssh_data(self, randpool, data): -
147 """ -148 Sign a blob of data with this private key, and return a L{Message} -149 representing an SSH signature message. -150 -151 @param randpool: a secure random number generator. -152 @type randpool: L{Crypto.Util.randpool.RandomPool} -153 @param data: the data to sign. -154 @type data: str -155 @return: an SSH signature message. -156 @rtype: L{Message} -157 """ -158 return '' -
159 -
160 - def verify_ssh_sig(self, data, msg): -
161 """ -162 Given a blob of data, and an SSH message representing a signature of -163 that data, verify that it was signed with this key. -164 -165 @param data: the data that was signed. -166 @type data: str -167 @param msg: an SSH signature message -168 @type msg: L{Message} -169 @return: C{True} if the signature verifies correctly; C{False} -170 otherwise. -171 @rtype: boolean -172 """ -173 return False -
174 -
175 - def from_private_key_file(cls, filename, password=None): -
176 """ -177 Create a key object by reading a private key file. If the private -178 key is encrypted and C{password} is not C{None}, the given password -179 will be used to decrypt the key (otherwise L{PasswordRequiredException} -180 is thrown). Through the magic of python, this factory method will -181 exist in all subclasses of PKey (such as L{RSAKey} or L{DSSKey}), but -182 is useless on the abstract PKey class. -183 -184 @param filename: name of the file to read -185 @type filename: str -186 @param password: an optional password to use to decrypt the key file, -187 if it's encrypted -188 @type password: str -189 @return: a new key object based on the given private key -190 @rtype: L{PKey} -191 -192 @raise IOError: if there was an error reading the file -193 @raise PasswordRequiredException: if the private key file is -194 encrypted, and C{password} is C{None} -195 @raise SSHException: if the key file is invalid -196 """ -197 key = cls(filename=filename, password=password) -198 return key -
199 from_private_key_file = classmethod(from_private_key_file) -200 -
201 - def from_private_key(cls, file_obj, password=None): -
202 """ -203 Create a key object by reading a private key from a file (or file-like) -204 object. If the private key is encrypted and C{password} is not C{None}, -205 the given password will be used to decrypt the key (otherwise -206 L{PasswordRequiredException} is thrown). -207 -208 @param file_obj: the file to read from -209 @type file_obj: file -210 @param password: an optional password to use to decrypt the key, if it's -211 encrypted -212 @type password: str -213 @return: a new key object based on the given private key -214 @rtype: L{PKey} -215 -216 @raise IOError: if there was an error reading the key -217 @raise PasswordRequiredException: if the private key file is encrypted, -218 and C{password} is C{None} -219 @raise SSHException: if the key file is invalid -220 """ -221 key = cls(file_obj=file_obj, password=password) -222 return key -
223 from_private_key = classmethod(from_private_key) -224 -
225 - def write_private_key_file(self, filename, password=None): -
226 """ -227 Write private key contents into a file. If the password is not -228 C{None}, the key is encrypted before writing. -229 -230 @param filename: name of the file to write -231 @type filename: str -232 @param password: an optional password to use to encrypt the key file -233 @type password: str -234 -235 @raise IOError: if there was an error writing the file -236 @raise SSHException: if the key is invalid -237 """ -238 raise Exception('Not implemented in PKey') -
239 -
240 - def write_private_key(self, file_obj, password=None): -
241 """ -242 Write private key contents into a file (or file-like) object. If the -243 password is not C{None}, the key is encrypted before writing. -244 -245 @param file_obj: the file object to write into -246 @type file_obj: file -247 @param password: an optional password to use to encrypt the key -248 @type password: str -249 -250 @raise IOError: if there was an error writing to the file -251 @raise SSHException: if the key is invalid -252 """ -253 raise Exception('Not implemented in PKey') -
254 -
255 - def _read_private_key_file(self, tag, filename, password=None): -
256 """ -257 Read an SSH2-format private key file, looking for a string of the type -258 C{"BEGIN xxx PRIVATE KEY"} for some C{xxx}, base64-decode the text we -259 find, and return it as a string. If the private key is encrypted and -260 C{password} is not C{None}, the given password will be used to decrypt -261 the key (otherwise L{PasswordRequiredException} is thrown). -262 -263 @param tag: C{"RSA"} or C{"DSA"}, the tag used to mark the data block. -264 @type tag: str -265 @param filename: name of the file to read. -266 @type filename: str -267 @param password: an optional password to use to decrypt the key file, -268 if it's encrypted. -269 @type password: str -270 @return: data blob that makes up the private key. -271 @rtype: str -272 -273 @raise IOError: if there was an error reading the file. -274 @raise PasswordRequiredException: if the private key file is -275 encrypted, and C{password} is C{None}. -276 @raise SSHException: if the key file is invalid. -277 """ -278 f = open(filename, 'r') -279 data = self._read_private_key(tag, f, password) -280 f. 47 +
48 - def __init__(self, msg=None, data=None): +
49 """ + 50 Create a new instance of this public key type. If C{msg} is given, + 51 the key's public part(s) will be filled in from the message. If + 52 C{data} is given, the key's public part(s) will be filled in from + 53 the string. + 54 + 55 @param msg: an optional SSH L{Message} containing a public key of this + 56 type. + 57 @type msg: L{Message} + 58 @param data: an optional string containing a public key of this type + 59 @type data: str + 60 + 61 @raise SSHException: if a key cannot be created from the C{data} or + 62 C{msg} given, or no key was passed in. + 63 """ + 64 pass +
65 +
66 - def __str__(self): +
67 """ + 68 Return a string of an SSH L{Message} made up of the public part(s) of + 69 this key. This string is suitable for passing to L{__init__} to + 70 re-create the key object later. + 71 + 72 @return: string representation of an SSH key message. + 73 @rtype: str + 74 """ + 75 return '' +
76 +
77 - def __cmp__(self, other): +
78 """ + 79 Compare this key to another. Returns 0 if this key is equivalent to + 80 the given key, or non-0 if they are different. Only the public parts + 81 of the key are compared, so a public key will compare equal to its + 82 corresponding private key. + 83 + 84 @param other: key to compare to. + 85 @type other: L{PKey} + 86 @return: 0 if the two keys are equivalent, non-0 otherwise. + 87 @rtype: int + 88 """ + 89 hs = hash(self) + 90 ho = hash(other) + 91 if hs != ho: + 92 return cmp(hs, ho) + 93 return cmp(str(self), str(other)) +
94 +
95 - def get_name(self): +
96 """ + 97 Return the name of this private key implementation. + 98 + 99 @return: name of this private key type, in SSH terminology (for +100 example, C{"ssh-rsa"}). +101 @rtype: str +102 """ +103 return '' +
104 +
105 - def get_bits(self): +
106 """ +107 Return the number of significant bits in this key. This is useful +108 for judging the relative security of a key. +109 +110 @return: bits in the key. +111 @rtype: int +112 """ +113 return 0 +
114 +
115 - def can_sign(self): +
116 """ +117 Return C{True} if this key has the private part necessary for signing +118 data. +119 +120 @return: C{True} if this is a private key. +121 @rtype: bool +122 """ +123 return False +
124 +
125 - def get_fingerprint(self): +
126 """ +127 Return an MD5 fingerprint of the public part of this key. Nothing +128 secret is revealed. +129 +130 @return: a 16-byte string (binary) of the MD5 fingerprint, in SSH +131 format. +132 @rtype: str +133 """ +134 return MD5.new(str(self)).digest() +
135 +
136 - def get_base64(self): +
137 """ +138 Return a base64 string containing the public part of this key. Nothing +139 secret is revealed. This format is compatible with that used to store +140 public key files or recognized host keys. +141 +142 @return: a base64 string containing the public part of the key. +143 @rtype: str +144 """ +145 return base64.encodestring(str(self)).replace('\n', '') +
146 +
147 - def sign_ssh_data(self, rng, data): +
148 """ +149 Sign a blob of data with this private key, and return a L{Message} +150 representing an SSH signature message. +151 +152 @param rng: a secure random number generator. +153 @type rng: L{Crypto.Util.rng.RandomPool} +154 @param data: the data to sign. +155 @type data: str +156 @return: an SSH signature message. +157 @rtype: L{Message} +158 """ +159 return '' +
160 +
161 - def verify_ssh_sig(self, data, msg): +
162 """ +163 Given a blob of data, and an SSH message representing a signature of +164 that data, verify that it was signed with this key. +165 +166 @param data: the data that was signed. +167 @type data: str +168 @param msg: an SSH signature message +169 @type msg: L{Message} +170 @return: C{True} if the signature verifies correctly; C{False} +171 otherwise. +172 @rtype: boolean +173 """ +174 return False +
175 +
176 - def from_private_key_file(cls, filename, password=None): +
177 """ +178 Create a key object by reading a private key file. If the private +179 key is encrypted and C{password} is not C{None}, the given password +180 will be used to decrypt the key (otherwise L{PasswordRequiredException} +181 is thrown). Through the magic of python, this factory method will +182 exist in all subclasses of PKey (such as L{RSAKey} or L{DSSKey}), but +183 is useless on the abstract PKey class. +184 +185 @param filename: name of the file to read +186 @type filename: str +187 @param password: an optional password to use to decrypt the key file, +188 if it's encrypted +189 @type password: str +190 @return: a new key object based on the given private key +191 @rtype: L{PKey} +192 +193 @raise IOError: if there was an error reading the file +194 @raise PasswordRequiredException: if the private key file is +195 encrypted, and C{password} is C{None} +196 @raise SSHException: if the key file is invalid +197 """ +198 key = cls(filename=filename, password=password) +199 return key +
200 from_private_key_file = classmethod(from_private_key_file) +201 +
202 - def from_private_key(cls, file_obj, password=None): +
203 """ +204 Create a key object by reading a private key from a file (or file-like) +205 object. If the private key is encrypted and C{password} is not C{None}, +206 the given password will be used to decrypt the key (otherwise +207 L{PasswordRequiredException} is thrown). +208 +209 @param file_obj: the file to read from +210 @type file_obj: file +211 @param password: an optional password to use to decrypt the key, if it's +212 encrypted +213 @type password: str +214 @return: a new key object based on the given private key +215 @rtype: L{PKey} +216 +217 @raise IOError: if there was an error reading the key +218 @raise PasswordRequiredException: if the private key file is encrypted, +219 and C{password} is C{None} +220 @raise SSHException: if the key file is invalid +221 """ +222 key = cls(file_obj=file_obj, password=password) +223 return key +
224 from_private_key = classmethod(from_private_key) +225 +
226 - def write_private_key_file(self, filename, password=None): +
227 """ +228 Write private key contents into a file. If the password is not +229 C{None}, the key is encrypted before writing. +230 +231 @param filename: name of the file to write +232 @type filename: str +233 @param password: an optional password to use to encrypt the key file +234 @type password: str +235 +236 @raise IOError: if there was an error writing the file +237 @raise SSHException: if the key is invalid +238 """ +239 raise Exception('Not implemented in PKey') +
240 +
241 - def write_private_key(self, file_obj, password=None): +
242 """ +243 Write private key contents into a file (or file-like) object. If the +244 password is not C{None}, the key is encrypted before writing. +245 +246 @param file_obj: the file object to write into +247 @type file_obj: file +248 @param password: an optional password to use to encrypt the key +249 @type password: str +250 +251 @raise IOError: if there was an error writing to the file +252 @raise SSHException: if the key is invalid +253 """ +254 raise Exception('Not implemented in PKey') +
255 +
256 - def _read_private_key_file(self, tag, filename, password=None): +
257 """ +258 Read an SSH2-format private key file, looking for a string of the type +259 C{"BEGIN xxx PRIVATE KEY"} for some C{xxx}, base64-decode the text we +260 find, and return it as a string. If the private key is encrypted and +261 C{password} is not C{None}, the given password will be used to decrypt +262 the key (otherwise L{PasswordRequiredException} is thrown). +263 +264 @param tag: C{"RSA"} or C{"DSA"}, the tag used to mark the data block. +265 @type tag: str +266 @param filename: name of the file to read. +267 @type filename: str +268 @param password: an optional password to use to decrypt the key file, +269 if it's encrypted. +270 @type password: str +271 @return: data blob that makes up the private key. +272 @rtype: str +273 +274 @raise IOError: if there was an error reading the file. +275 @raise PasswordRequiredException: if the private key file is +276 encrypted, and C{password} is C{None}. +277 @raise SSHException: if the key file is invalid. +278 """ +279 f = open(filename, 'r') +280 data = self._read_private_key(tag, f, password) +281 f.close() -281 return data -
282 -
283 - def _read_private_key(self, tag, f, password=None): -
284 lines = f.readlines() -285 start = 0 -286 while (start < len(lines)) and (lines[start].strip() != '-----BEGIN ' + tag + ' PRIVATE KEY-----'): -287 start += 1 -288 if start >= len(lines): -289 raise SSHException('not a valid ' + tag + ' private key file') -290 # parse any headers first -291 headers = {} -292 start += 1 -293 while start < len(lines): -294 l = lines[start].split(': ') -295 if len(l) == 1: -296 break -297 headers[l[0].lower()] = l[1].strip() -298 start += 1 -299 # find end -300 end = start -301 while (lines[end].strip() != '-----END ' + tag + ' PRIVATE KEY-----') and (end < len(lines)): -302 end += 1 -303 # if we trudged to the end of the file, just try to cope. -304 try: -305 data = base64.decodestring(''.join(lines[start:end])) -306 except base64.binascii.Error, e: -307 raise SSHException('base64 decoding error: ' + str(e)) -308 if 'proc-type' not in headers: -309 # unencryped: done -310 return data -311 # encrypted keyfile: will need a password -312 if headers['proc-type'] != '4,ENCRYPTED': -313 raise SSHException('Unknown private key structure "%s"' % headers['proc-type']) -314 try: -315 encryption_type, saltstr = headers['dek-info'].split(',') -316 except: -317 raise SSHException('Can\'t parse DEK-info in private key file') -318 if encryption_type not in self._CIPHER_TABLE: -319 raise SSHException('Unknown private key cipher "%s"' % encryption_type) -320 # if no password was passed in, raise an exception pointing out that we need one -321 if password is None: -322 raise PasswordRequiredException('Private key file is encrypted') -323 cipher = self._CIPHER_TABLE[encryption_type]['cipher'] -324 keysize = self._CIPHER_TABLE[encryption_type]['keysize'] -325 mode = self._CIPHER_TABLE[encryption_type]['mode'] -326 salt = unhexlify(saltstr) -327 key = util.generate_key_bytes(MD5, salt, password, keysize) -328 return cipher.new(key, mode, salt).decrypt(data) -
329 -
330 - def _write_private_key_file(self, tag, filename, data, password=None): -
331 """ -332 Write an SSH2-format private key file in a form that can be read by -333 paramiko or openssh. If no password is given, the key is written in -334 a trivially-encoded format (base64) which is completely insecure. If -335 a password is given, DES-EDE3-CBC is used. -336 -337 @param tag: C{"RSA"} or C{"DSA"}, the tag used to mark the data block. -338 @type tag: str -339 @param filename: name of the file to write. -340 @type filename: str -341 @param data: data blob that makes up the private key. -342 @type data: str -343 @param password: an optional password to use to encrypt the file. -344 @type password: str -345 -346 @raise IOError: if there was an error writing the file. -347 """ -348 f = open(filename, 'w', 0600) -349 # grrr... the mode doesn't always take hold -350 os.282 return data +
283 +
284 - def _read_private_key(self, tag, f, password=None): +
285 lines = f.readlines() +286 start = 0 +287 while (start < len(lines)) and (lines[start].strip() != '-----BEGIN ' + tag + ' PRIVATE KEY-----'): +288 start += 1 +289 if start >= len(lines): +290 raise SSHException('not a valid ' + tag + ' private key file') +291 # parse any headers first +292 headers = {} +293 start += 1 +294 while start < len(lines): +295 l = lines[start].split(': ') +296 if len(l) == 1: +297 break +298 headers[l[0].lower()] = l[1].strip() +299 start += 1 +300 # find end +301 end = start +302 while (lines[end].strip() != '-----END ' + tag + ' PRIVATE KEY-----') and (end < len(lines)): +303 end += 1 +304 # if we trudged to the end of the file, just try to cope. +305 try: +306 data = base64.decodestring(''.join(lines[start:end])) +307 except base64.binascii.Error, e: +308 raise SSHException('base64 decoding error: ' + str(e)) +309 if 'proc-type' not in headers: +310 # unencryped: done +311 return data +312 # encrypted keyfile: will need a password +313 if headers['proc-type'] != '4,ENCRYPTED': +314 raise SSHException('Unknown private key structure "%s"' % headers['proc-type']) +315 try: +316 encryption_type, saltstr = headers['dek-info'].split(',') +317 except: +318 raise SSHException('Can\'t parse DEK-info in private key file') +319 if encryption_type not in self._CIPHER_TABLE: +320 raise SSHException('Unknown private key cipher "%s"' % encryption_type) +321 # if no password was passed in, raise an exception pointing out that we need one +322 if password is None: +323 raise PasswordRequiredException('Private key file is encrypted') +324 cipher = self._CIPHER_TABLE[encryption_type]['cipher'] +325 keysize = self._CIPHER_TABLE[encryption_type]['keysize'] +326 mode = self._CIPHER_TABLE[encryption_type]['mode'] +327 salt = unhexlify(saltstr) +328 key = util.generate_key_bytes(MD5, salt, password, keysize) +329 return cipher.new(key, mode, salt).decrypt(data) +
330 +
331 - def _write_private_key_file(self, tag, filename, data, password=None): +
332 """ +333 Write an SSH2-format private key file in a form that can be read by +334 paramiko or openssh. If no password is given, the key is written in +335 a trivially-encoded format (base64) which is completely insecure. If +336 a password is given, DES-EDE3-CBC is used. +337 +338 @param tag: C{"RSA"} or C{"DSA"}, the tag used to mark the data block. +339 @type tag: str +340 @param filename: name of the file to write. +341 @type filename: str +342 @param data: data blob that makes up the private key. +343 @type data: str +344 @param password: an optional password to use to encrypt the file. +345 @type password: str +346 +347 @raise IOError: if there was an error writing the file. +348 """ +349 f = open(filename, 'w', 0600) +350 # grrr... the mode doesn't always take hold +351 os.chmod(filename, 0600) -351 self._write_private_key(tag, f, data, password) -352 f.352 self._write_private_key(tag, f, data, password) +353 f.close() -
353 -
354 - def _write_private_key(self, tag, f, data, password=None): -
355 f.354 +
355 - def _write_private_key(self, tag, f, data, password=None): +
356 f.write('-----BEGIN %s PRIVATE KEY-----\n' % tag) -356 if password is not None: -357 # since we only support one cipher here, use it -358 cipher_name = self._CIPHER_TABLE.keys()[0] -359 cipher = self._CIPHER_TABLE[cipher_name]['cipher'] -360 keysize = self._CIPHER_TABLE[cipher_name]['keysize'] -361 blocksize = self._CIPHER_TABLE[cipher_name]['blocksize'] -362 mode = self._CIPHER_TABLE[cipher_name]['mode'] -363 salt = randpool.get_bytes(8) -364 key = util.generate_key_bytes(MD5, salt, password, keysize) -365 if len(data) % blocksize != 0: -366 n = blocksize - len(data) % blocksize -367 #data += randpool.get_bytes(n) -368 # that would make more sense ^, but it confuses openssh. -369 data += '\0' * n -370 data = cipher.new(key, mode, salt).encrypt(data) -371 f.357 if password is not None: +358 # since we only support one cipher here, use it +359 cipher_name = self._CIPHER_TABLE.keys()[0] +360 cipher = self._CIPHER_TABLE[cipher_name]['cipher'] +361 keysize = self._CIPHER_TABLE[cipher_name]['keysize'] +362 blocksize = self._CIPHER_TABLE[cipher_name]['blocksize'] +363 mode = self._CIPHER_TABLE[cipher_name]['mode'] +364 salt = rng.read(8) +365 key = util.generate_key_bytes(MD5, salt, password, keysize) +366 if len(data) % blocksize != 0: +367 n = blocksize - len(data) % blocksize +368 #data += rng.read(n) +369 # that would make more sense ^, but it confuses openssh. +370 data += '\0' * n +371 data = cipher.new(key, mode, salt).encrypt(data) +372 f.write('Proc-Type: 4,ENCRYPTED\n') -372 f.373 f.write('DEK-Info: %s,%s\n' % (cipher_name, hexlify(salt).upper())) -373 f.374 f.write('\n') -374 s = base64.encodestring(data) -375 # re-wrap to 64-char lines -376 s = ''.join(s.split('\n')) -377 s = '\n'.join([s[i : i+64] for i in range(0, len(s), 64)]) -378 f.375 s = base64.encodestring(data) +376 # re-wrap to 64-char lines +377 s = ''.join(s.split('\n')) +378 s = '\n'.join([s[i : i+64] for i in range(0, len(s), 64)]) +379 f.write(s) -379 f.380 f.write('\n') -380 f.381 f.write('-----END %s PRIVATE KEY-----\n' % tag) -
381