Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(52)

Side by Side Diff: third_party/twisted_8_1/twisted/conch/ssh/keys.py

Issue 12261012: Remove third_party/twisted_8_1 (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/tools/build
Patch Set: Created 7 years, 10 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
OLDNEW
(Empty)
1 # -*- test-case-name: twisted.conch.test.test_keys -*-
2 # Copyright (c) 2001-2008 Twisted Matrix Laboratories.
3 # See LICENSE for details.
4
5 #
6
7 """
8 Handling of RSA and DSA keys.
9
10 Maintainer: U{Paul Swartz}
11 """
12
13 # base library imports
14 import base64
15 import sha, md5
16 import warnings
17
18 # external library imports
19 from Crypto.Cipher import DES3
20 from Crypto.PublicKey import RSA, DSA
21 from Crypto import Util
22
23 # twisted
24 from twisted.python import randbytes
25
26 # sibling imports
27 from twisted.conch.ssh import asn1, common, sexpy
28
29
30 class BadKeyError(Exception):
31 """
32 Raised when a key isn't what we expected from it.
33
34 XXX: we really need to check for bad keys
35 """
36
37 class EncryptedKeyError(Exception):
38 """
39 Raised when an encrypted key is presented to fromString/fromFile without
40 a password.
41 """
42
43 class Key(object):
44 """
45 An object representing a key. A key can be either a public or
46 private key. A public key can verify a signature; a private key can
47 create or verify a signature. To generate a string that can be stored
48 on disk, use the toString method. If you have a private key, but want
49 the string representation of the public key, use Key.public().toString().
50
51 @ivar keyObject: The C{Crypto.PublicKey.pubkey.pubkey} object that
52 operations are performed with.
53 """
54
55 def fromFile(Class, filename, type=None, passphrase=None):
56 """
57 Return a Key object corresponding to the data in filename. type
58 and passphrase function as they do in fromString.
59 """
60 return Class.fromString(file(filename, 'rb').read(), type, passphrase)
61 fromFile = classmethod(fromFile)
62
63 def fromString(Class, data, type=None, passphrase=None):
64 """
65 Return a Key object corresponding to the string data.
66 type is optionally the type of string, matching a _fromString_*
67 method. Otherwise, the _guessStringType() classmethod will be used
68 to guess a type. If the key is encrypted, passphrase is used as
69 the decryption key.
70
71 @type data: C{str}
72 @type type: C{None}/C{str}
73 @type passphrase: C{None}/C{str}
74 @rtype: C{Key}
75 """
76 if type is None:
77 type = Class._guessStringType(data)
78 if type is None:
79 raise BadKeyError('cannot guess the type of %r' % data)
80 method = getattr(Class, '_fromString_%s' % type.upper(), None)
81 if method is None:
82 raise BadKeyError('no _fromString method for %s' % type)
83 if method.func_code.co_argcount == 2: # no passphrase
84 if passphrase:
85 raise BadKeyError('key not encrypted')
86 return method(data)
87 else:
88 return method(data, passphrase)
89 fromString = classmethod(fromString)
90
91 def _fromString_BLOB(Class, blob):
92 """
93 Return a public key object corresponding to this public key blob.
94 The format of a RSA public key blob is::
95 string 'ssh-rsa'
96 integer e
97 integer n
98
99 The format of a DSA public key blob is::
100 string 'ssh-dss'
101 integer p
102 integer q
103 integer g
104 integer y
105
106 @type blob: C{str}
107 @return: a C{Crypto.PublicKey.pubkey.pubkey} object
108 @raises BadKeyError: if the key type (the first string) is unknown.
109 """
110 keyType, rest = common.getNS(blob)
111 if keyType == 'ssh-rsa':
112 e, n, rest = common.getMP(rest, 2)
113 return Class(RSA.construct((n, e)))
114 elif keyType == 'ssh-dss':
115 p, q, g, y, rest = common.getMP(rest, 4)
116 return Class(DSA.construct((y, g, p, q)))
117 else:
118 raise BadKeyError('unknown blob type: %s' % keyType)
119 _fromString_BLOB = classmethod(_fromString_BLOB)
120
121 def _fromString_PUBLIC_OPENSSH(Class, data):
122 """
123 Return a public key object corresponding to this OpenSSH public key
124 string. The format of an OpenSSH public key string is::
125 <key type> <base64-encoded public key blob>
126
127 @type data: C{str}
128 @return: A {Crypto.PublicKey.pubkey.pubkey} object
129 @raises BadKeyError: if the blob type is unknown.
130 """
131 blob = base64.decodestring(data.split()[1])
132 return Class._fromString_BLOB(blob)
133 _fromString_PUBLIC_OPENSSH = classmethod(_fromString_PUBLIC_OPENSSH)
134
135 def _fromString_PRIVATE_OPENSSH(Class, data, passphrase):
136 """
137 Return a private key object corresponding to this OpenSSH private key
138 string. If the key is encrypted, passphrase MUST be provided.
139 Providing a passphrase for an unencrypted key is an error.
140
141 The format of an OpenSSH private key string is::
142 -----BEGIN <key type> PRIVATE KEY-----
143 [Proc-Type: 4,ENCRYPTED
144 DEK-Info: DES-EDE3-CBC,<initialization value>]
145 <base64-encoded ASN.1 structure>
146 ------END <key type> PRIVATE KEY------
147
148 The ASN.1 structure of a RSA key is::
149 (0, n, e, d, p, q)
150
151 The ASN.1 structure of a DSA key is::
152 (0, p, q, g, y, x)
153
154 @type data: C{str}
155 @type passphrase: C{str}
156 @return: a C{Crypto.PublicKey.pubkey.pubkey} object
157 @raises BadKeyError: if
158 * a passphrase is provided for an unencrypted key
159 * a passphrase is not provided for an encrypted key
160 * the ASN.1 encoding is incorrect
161 """
162 lines = [x + '\n' for x in data.split('\n')]
163 kind = lines[0][11:14]
164 if lines[1].startswith('Proc-Type: 4,ENCRYPTED'): # encrypted key
165 ivdata = lines[2].split(',')[1][:-1]
166 iv = ''.join([chr(int(ivdata[i:i + 2], 16)) for i in range(0,
167 len(ivdata), 2)])
168 if not passphrase:
169 raise EncryptedKeyError('encrypted key with no passphrase')
170 ba = md5.new(passphrase + iv).digest()
171 bb = md5.new(ba + passphrase + iv).digest()
172 decKey = (ba + bb)[:24]
173 b64Data = base64.decodestring(''.join(lines[3:-1]))
174 keyData = DES3.new(decKey, DES3.MODE_CBC, iv).decrypt(b64Data)
175 removeLen = ord(keyData[-1])
176 keyData = keyData[:-removeLen]
177 else:
178 keyData = base64.decodestring(''.join(lines[1:-1]))
179 try:
180 decodedKey = asn1.parse(keyData)
181 except Exception, e:
182 raise BadKeyError, 'something wrong with decode'
183 if kind == 'RSA':
184 if len(decodedKey) == 2: # alternate RSA key
185 decodedKey = decodedKey[0]
186 n, e, d, p, q = decodedKey[1:6]
187 if p > q: # make p smaller than q
188 p, q = q, p
189 return Class(RSA.construct((n, e, d, p, q)))
190 elif kind == 'DSA':
191 p, q, g, y, x = decodedKey[1: 6]
192 return Class(DSA.construct((y, g, p, q, x)))
193 _fromString_PRIVATE_OPENSSH = classmethod(_fromString_PRIVATE_OPENSSH)
194
195 def _fromString_PUBLIC_LSH(Class, data):
196 """
197 Return a public key corresponding to this LSH public key string.
198 The LSH public key string format is::
199 <s-expression: ('public-key', (<key type>, (<name, <value>)+))>
200
201 The names for a RSA (key type 'rsa-pkcs1-sha1') key are: n, e.
202 The names for a DSA (key type 'dsa') key are: y, g, p, q.
203
204 @type data: C{str}
205 @return: a C{Crypto.PublicKey.pubkey.pubkey} object
206 @raises BadKeyError: if the key type is unknown
207 """
208 sexp = sexpy.parse(base64.decodestring(data[1:-1]))
209 assert sexp[0] == 'public-key'
210 kd = {}
211 for name, data in sexp[1][1:]:
212 kd[name] = common.getMP(common.NS(data))[0]
213 if sexp[1][0] == 'dsa':
214 return Class(DSA.construct((kd['y'], kd['g'], kd['p'], kd['q'])))
215 elif sexp[1][0] == 'rsa-pkcs1-sha1':
216 return Class(RSA.construct((kd['n'], kd['e'])))
217 else:
218 raise BadKeyError('unknown lsh key type %s' % sexp[1][0])
219 _fromString_PUBLIC_LSH = classmethod(_fromString_PUBLIC_LSH)
220
221 def _fromString_PRIVATE_LSH(Class, data):
222 """
223 Return a private key corresponding to this LSH private key string.
224 The LSH private key string format is::
225 <s-expression: ('private-key', (<key type>, (<name>, <value>)+))>
226
227 The names for a RSA (key type 'rsa-pkcs1-sha1') key are: n, e, d, p, q.
228 The names for a DSA (key type 'dsa') key are: y, g, p, q, x.
229
230 @type data: C{str}
231 @return: a {Crypto.PublicKey.pubkey.pubkey} object
232 @raises BadKeyError: if the key type is unknown
233 """
234 sexp = sexpy.parse(data)
235 assert sexp[0] == 'private-key'
236 kd = {}
237 for name, data in sexp[1][1:]:
238 kd[name] = common.getMP(common.NS(data))[0]
239 if sexp[1][0] == 'dsa':
240 assert len(kd) == 5, len(kd)
241 return Class(DSA.construct((kd['y'], kd['g'], kd['p'],
242 kd['q'], kd['x'])))
243 elif sexp[1][0] == 'rsa-pkcs1':
244 assert len(kd) == 8, len(kd)
245 if kd['p'] > kd['q']: # make p smaller than q
246 kd['p'], kd['q'] = kd['q'], kd['p']
247 return Class(RSA.construct((kd['n'], kd['e'], kd['d'],
248 kd['p'], kd['q'])))
249 else:
250 raise BadKeyError('unknown lsh key type %s' % sexp[1][0])
251 _fromString_PRIVATE_LSH = classmethod(_fromString_PRIVATE_LSH)
252
253 def _fromString_AGENTV3(Class, data):
254 """
255 Return a private key object corresponsing to the Secure Shell Key
256 Agent v3 format.
257
258 The SSH Key Agent v3 format for a RSA key is::
259 string 'ssh-rsa'
260 integer e
261 integer d
262 integer n
263 integer u
264 integer p
265 integer q
266
267 The SSH Key Agent v3 format for a DSA key is::
268 string 'ssh-dss'
269 integer p
270 integer q
271 integer g
272 integer y
273 integer x
274
275 @type data: C{str}
276 @return: a C{Crypto.PublicKey.pubkey.pubkey} object
277 @raises BadKeyError: if the key type (the first string) is unknown
278 """
279 keyType, data = common.getNS(data)
280 if keyType == 'ssh-dss':
281 p, data = common.getMP(data)
282 q, data = common.getMP(data)
283 g, data = common.getMP(data)
284 y, data = common.getMP(data)
285 x, data = common.getMP(data)
286 return Class(DSA.construct((y,g,p,q,x)))
287 elif keyType == 'ssh-rsa':
288 e, data = common.getMP(data)
289 d, data = common.getMP(data)
290 n, data = common.getMP(data)
291 u, data = common.getMP(data)
292 p, data = common.getMP(data)
293 q, data = common.getMP(data)
294 return Class(RSA.construct((n,e,d,p,q,u)))
295 else:
296 raise BadKeyError("unknown key type %s" % keyType)
297 _fromString_AGENTV3 = classmethod(_fromString_AGENTV3)
298
299 def _guessStringType(Class, data):
300 """
301 Guess the type of key in data. The types map to _fromString_*
302 methods.
303 """
304 if data.startswith('ssh-'):
305 return 'public_openssh'
306 elif data.startswith('-----BEGIN'):
307 return 'private_openssh'
308 elif data.startswith('{'):
309 return 'public_lsh'
310 elif data.startswith('('):
311 return 'private_lsh'
312 elif data.startswith('\x00\x00\x00\x07ssh-'):
313 ignored, rest = common.getNS(data)
314 count = 0
315 while rest:
316 count += 1
317 ignored, rest = common.getMP(rest)
318 if count > 4:
319 return 'agentv3'
320 else:
321 return 'blob'
322 _guessStringType = classmethod(_guessStringType)
323
324 def __init__(self, keyObject):
325 """
326 Initialize a PublicKey with a C{Crypto.PublicKey.pubkey.pubkey}
327 object.
328
329 @type keyObject: C{Crypto.PublicKey.pubkey.pubkey}
330 """
331 self.keyObject = keyObject
332
333 def __eq__(self, other):
334 """
335 Return True if other represents an object with the same key.
336 """
337 if type(self) == type(other):
338 return self.type() == other.type() and self.data() == other.data()
339 else:
340 return NotImplemented
341
342 def __ne__(self, other):
343 """
344 Return True if other represents anything other than this key.
345 """
346 result = self.__eq__(other)
347 if result == NotImplemented:
348 return result
349 return not result
350
351 def __repr__(self):
352 """
353 Return a pretty representation of this object.
354 """
355 lines = ['<%s %s (%s bits)' % (self.type(),
356 self.isPublic() and 'Public Key' or 'Private Key',
357 self.keyObject.size())]
358 for k, v in self.data().items():
359 lines.append('attr %s:' % k)
360 by = common.MP(v)[4:]
361 while by:
362 m = by[:15]
363 by = by[15:]
364 o = ''
365 for c in m:
366 o = o + '%02x:' % ord(c)
367 if len(m) < 15:
368 o = o[:-1]
369 lines.append('\t' + o)
370 lines[-1] = lines[-1] + '>'
371 return '\n'.join(lines)
372
373 def isPublic(self):
374 """
375 Returns True if this Key is a public key.
376 """
377 return not self.keyObject.has_private()
378
379 def public(self):
380 """
381 Returns a version of this key containing only the public key data.
382 If this is a public key, this may or may not be the same object
383 as self.
384 """
385 return Key(self.keyObject.publickey())
386
387 def type(self):
388 """
389 Return the type of the object we wrap. Currently this can only be
390 'RSA' or 'DSA'.
391 """
392 # the class is Crypto.PublicKey.<type>.<stuff we don't care about>
393 klass = str(self.keyObject.__class__)
394 if klass.startswith('Crypto.PublicKey'):
395 type = klass.split('.')[2]
396 else:
397 raise RuntimeError('unknown type of object: %r' % self.keyObject)
398 if type in ('RSA', 'DSA'):
399 return type
400 else:
401 raise RuntimeError('unknown type of key: %s' % type)
402
403 def sshType(self):
404 """
405 Return the type of the object we wrap as defined in the ssh protocol.
406 Currently this can only be 'ssh-rsa' or 'ssh-dss'.
407 """
408 return {'RSA':'ssh-rsa', 'DSA':'ssh-dss'}[self.type()]
409
410 def data(self):
411 """
412 Return the values of the public key as a dictionary.
413
414 @rtype: C{dict}
415 """
416 keyData = {}
417 for name in self.keyObject.keydata:
418 value = getattr(self.keyObject, name, None)
419 if value is not None:
420 keyData[name] = value
421 return keyData
422
423 def blob(self):
424 """
425 Return the public key blob for this key. The blob is the
426 over-the-wire format for public keys:
427
428 RSA keys::
429 string 'ssh-rsa'
430 integer e
431 integer n
432
433 DSA keys::
434 string 'ssh-dss'
435 integer p
436 integer q
437 integer g
438 integer y
439
440 @rtype: C{str}
441 """
442 type = self.type()
443 data = self.data()
444 if type == 'RSA':
445 return (common.NS('ssh-rsa') + common.MP(data['e']) +
446 common.MP(data['n']))
447 elif type == 'DSA':
448 return (common.NS('ssh-dss') + common.MP(data['p']) +
449 common.MP(data['q']) + common.MP(data['g']) +
450 common.MP(data['y']))
451
452 def toString(self, type, extra=None):
453 """
454 Create a string representation of this key. If the key is a
455 private key and you want the represenation of its public key,
456 use .public().toString(). type maps to a _toString_* method.
457 The extra paramater allows passing data to some of the method.
458 For public OpenSSH keys, it represents a comment.
459 For private OpenSSH keys, it represents a passphrase.
460
461 @type type: C{str}
462 @type extra: C{str}
463 @rtype: C{str}
464 """
465 method = getattr(self, '_toString_%s' % type.upper(), None)
466 if method is None:
467 raise BadKeyError('unknown type: %s' % type)
468 if method.func_code.co_argcount == 2:
469 return method(extra)
470 else:
471 return method()
472
473 def _toString_OPENSSH(self, extra):
474 """
475 Return a public or private OpenSSH string. See
476 _fromString_PUBLIC_OPENSSH and _fromString_PRIVATE_OPENSSH for the
477 string formats. If extra is present, it represents a comment for a
478 public key, or a passphrase for a private key.
479
480 @type extra: C{str}
481 @rtype: C{str}
482 """
483 data = self.data()
484 if self.isPublic():
485 b64Data = base64.encodestring(self.blob()).replace('\n', '')
486 if not extra:
487 extra = ''
488 return ('%s %s %s' % (self.sshType(), b64Data, extra)).strip()
489 else:
490 lines = ['-----BEGIN %s PRIVATE KEY-----' % self.type()]
491 if self.type() == 'RSA':
492 p, q = data['p'], data['q']
493 objData = (0, data['n'], data['e'], data['d'], q, p,
494 data['d'] % (q - 1), data['d'] % (p - 1),
495 data['u'])
496 else:
497 objData = (0, data['p'], data['q'], data['g'], data['y'],
498 data['x'])
499 if extra:
500 iv = randbytes.secureRandom(8)
501 hexiv = ''.join(['%02X' % ord(x) for x in iv])
502 lines.append('Proc-Type: 4,ENCRYPTED')
503 lines.append('DEK-Info: DES-EDE3-CBC,%s\n' % hexiv)
504 ba = md5.new(extra + iv).digest()
505 bb = md5.new(ba + extra + iv).digest()
506 encKey = (ba + bb)[:24]
507 asn1Data = asn1.pack([objData])
508 if extra:
509 padLen = 8 - (len(asn1Data) % 8)
510 asn1Data += (chr(padLen) * padLen)
511 asn1Data = DES3.new(encKey, DES3.MODE_CBC,
512 iv).encrypt(asn1Data)
513 b64Data = base64.encodestring(asn1Data).replace('\n', '')
514 lines += [b64Data[i:i + 64] for i in range(0, len(b64Data), 64)]
515 lines.append('-----END %s PRIVATE KEY-----' % self.type())
516 return '\n'.join(lines)
517
518 def _toString_LSH(self):
519 """
520 Return a public or private LSH key. See _fromString_PUBLIC_LSH and
521 _fromString_PRIVATE_LSH for the key formats.
522
523 @rtype: C{str}
524 """
525 data = self.data()
526 if self.isPublic():
527 if self.type() == 'RSA':
528 keyData = sexpy.pack([['public-key', ['rsa-pkcs1-sha1',
529 ['n', common.MP(data['n'])[4:]],
530 ['e', common.MP(data['e'])[4:]]]]])
531 elif self.type() == 'DSA':
532 keyData = sexpy.pack([['public-key', ['dsa',
533 ['p', common.MP(data['p'])[4:]],
534 ['q', common.MP(data['q'])[4:]],
535 ['g', common.MP(data['g'])[4:]],
536 ['y', common.MP(data['y'])[4:]]]]])
537 return '{' + base64.encodestring(keyData).replace('\n', '') + '}'
538 else:
539 if self.type() == 'RSA':
540 p, q = data['p'], data['q']
541 return sexpy.pack([['private-key', ['rsa-pkcs1',
542 ['n', common.MP(data['n'])[4:]],
543 ['e', common.MP(data['e'])[4:]],
544 ['d', common.MP(data['d'])[4:]],
545 ['p', common.MP(q)[4:]],
546 ['q', common.MP(p)[4:]],
547 ['a', common.MP(data['d'] % (q - 1))[4:]],
548 ['b', common.MP(data['d'] % (p - 1))[4:]],
549 ['c', common.MP(data['u'])[4:]]]]])
550 elif self.type() == 'DSA':
551 return sexpy.pack([['private-key', ['dsa',
552 ['p', common.MP(data['p'])[4:]],
553 ['q', common.MP(data['q'])[4:]],
554 ['g', common.MP(data['g'])[4:]],
555 ['y', common.MP(data['y'])[4:]],
556 ['x', common.MP(data['x'])[4:]]]]])
557
558 def _toString_AGENTV3(self):
559 """
560 Return a private Secure Shell Agent v3 key. See
561 _fromString_AGENTV3 for the key format.
562
563 @rtype: C{str}
564 """
565 data = self.data()
566 if not self.isPublic():
567 if self.type() == 'RSA':
568 values = (data['e'], data['d'], data['n'], data['u'],
569 data['p'], data['q'])
570 elif self.type() == 'DSA':
571 values = (data['p'], data['q'], data['g'], data['y'],
572 data['x'])
573 return common.NS(self.sshType()) + ''.join(map(common.MP, values))
574
575
576 def sign(self, data):
577 """
578 Returns a signature with this Key.
579
580 @type data: C{str}
581 @rtype: C{str}
582 """
583 if self.type() == 'RSA':
584 digest = pkcs1Digest(data, self.keyObject.size()/8)
585 signature = self.keyObject.sign(digest, '')[0]
586 ret = common.NS(Util.number.long_to_bytes(signature))
587 elif self.type() == 'DSA':
588 digest = sha.new(data).digest()
589 randomBytes = randbytes.secureRandom(19)
590 sig = self.keyObject.sign(digest, randomBytes)
591 # SSH insists that the DSS signature blob be two 160-bit integers
592 # concatenated together. The sig[0], [1] numbers from obj.sign
593 # are just numbers, and could be any length from 0 to 160 bits.
594 # Make sure they are padded out to 160 bits (20 bytes each)
595 ret = common.NS(Util.number.long_to_bytes(sig[0], 20) +
596 Util.number.long_to_bytes(sig[1], 20))
597 return common.NS(self.sshType()) + ret
598
599 def verify(self, signature, data):
600 """
601 Returns true if the signature for data is valid for this Key.
602
603 @type signature: C{str}
604 @type data: C{str}
605 @rtype: C{bool}
606 """
607 signatureType, signature = common.getNS(signature)
608 if signatureType != self.sshType():
609 return False
610 if self.type() == 'RSA':
611 numbers = common.getMP(signature)
612 digest = pkcs1Digest(data, self.keyObject.size() / 8)
613 elif self.type() == 'DSA':
614 signature = common.getNS(signature)[0]
615 numbers = [Util.number.bytes_to_long(n) for n in signature[:20],
616 signature[20:]]
617 digest = sha.new(data).digest()
618 return self.keyObject.verify(digest, numbers)
619
620 def getPublicKeyString(filename=None, line=0, data=''):
621 """
622 Return a public key string suitable for being sent over the wire.
623 Takes a filename or data of a public key. Currently handles OpenSSH
624 and LSH keys.
625
626 This function has been deprecated since Twisted Conch 0.9. Use
627 Key.fromString() instead.
628
629 @type filename: C{str}
630 @type line: C{int}
631 @type data: C{str}
632 @rtype: C{str}
633 """
634 warnings.warn("getPublicKeyString is deprecated since Twisted Conch 0.9."
635 " Use Key.fromString().",
636 DeprecationWarning, stacklevel=2)
637 if filename and data:
638 raise BadKeyError("either filename or data, not both")
639 if filename:
640 lines = open(filename).readlines()
641 data = lines[line]
642 return Key.fromString(data).blob()
643
644 def makePublicKeyString(obj, comment='', kind='openssh'):
645 """
646 Return an public key given a C{Crypto.PublicKey.pubkey.pubkey}
647 object.
648 kind is one of ('openssh', 'lsh')
649
650 This function is deprecated since Twisted Conch 0.9. Instead use
651 Key(obj).toString().
652
653 @type obj: C{Crypto.PublicKey.pubkey.pubkey}
654 @type comment: C{str}
655 @type kind: C{str}
656 @rtype: C{str}
657 """
658 warnings.warn("makePublicKeyString is deprecated since Twisted Conch 0.9."
659 " Use Key(obj).toString().",
660 DeprecationWarning, stacklevel=2)
661 return Key(obj).public().toString(kind, comment)
662
663 def getPublicKeyObject(data):
664 """
665 Return a C{Crypto.PublicKey.pubkey.pubkey} corresponding to the SSHv2
666 public key data. data is in the over-the-wire public key format.
667
668 This function is deprecated since Twisted Conch 0.9. Instead, use
669 Key.fromString().
670
671 @type data: C{str}
672 @rtype: C{Crypto.PublicKey.pubkey.pubkey}
673 """
674 warnings.warn("getPublicKeyObject is deprecated since Twisted Conch 0.9."
675 " Use Key.fromString().",
676 DeprecationWarning, stacklevel=2)
677 return Key.fromString(data).keyObject
678
679 def getPrivateKeyObject(filename=None, data='', passphrase=''):
680 """
681 Return a C{Crypto.PublicKey.pubkey.pubkey} object corresponding to the
682 private key file/data. If the private key is encrypted, passphrase B{must}
683 be specified, other wise a L{BadKeyError} will be raised.
684
685 This method is deprecated since Twisted Conch 0.9. Instead, use
686 the fromString or fromFile classmethods of Key.
687
688 @type filename: C{str}
689 @type data: C{str}
690 @type passphrase: C{str}
691 @rtype: C{Crypto.PublicKey.pubkey.pubkey}
692 @raises BadKeyError: if the key is invalid or a passphrase is not specified
693 """
694 warnings.warn("getPrivateKeyObject is deprecated since Twisted Conch 0.9."
695 " Use Key.fromString().",
696 DeprecationWarning, stacklevel=2)
697 if filename and data:
698 raise BadKeyError("either filename or data, not both")
699 if filename:
700 return Key.fromFile(filename, passphrase=passphrase).keyObject
701 else:
702 return Key.fromString(data, passphrase=passphrase).keyObject
703
704 def makePrivateKeyString(obj, passphrase=None, kind='openssh'):
705 """
706 Return an OpenSSH-style private key for a
707 C{Crypto.PublicKey.pubkey.pubkey} object. If passphrase is given, encrypt
708 the private key with it.
709 kind is one of ('openssh', 'lsh', 'agentv3')
710
711 This function is deprecated since Twisted Conch 0.9. Instead use
712 Key(obj).toString().
713
714 @type obj: C{Crypto.PublicKey.pubkey.pubkey}
715 @type passphrase: C{str}/C{None}
716 @type kind: C{str}
717 @rtype: C{str}
718 """
719 warnings.warn("makePrivateKeyString is deprecated since Twisted Conch 0.9."
720 " Use Key(obj).toString().",
721 DeprecationWarning, stacklevel=2)
722 return Key(obj).toString(kind, passphrase)
723
724 def makePublicKeyBlob(obj):
725 """
726 Make a public key blob from a C{Crypto.PublicKey.pubkey.pubkey}.
727
728 This function is deprecated since Twisted Conch 0.9. Use
729 Key().blob() instead.
730 """
731 warnings.warn("makePublicKeyBlob is deprecated since Twisted Conch 0.9."
732 " Use Key(obj).blob().",
733 DeprecationWarning, stacklevel=2)
734 return Key(obj).blob()
735
736 def objectType(obj):
737 """
738 Return the SSH key type corresponding to a C{Crypto.PublicKey.pubkey.pubkey}
739 object.
740
741 @type obj: C{Crypto.PublicKey.pubkey.pubkey}
742 @rtype: C{str}
743 """
744 keyDataMapping = {
745 ('n', 'e', 'd', 'p', 'q'): 'ssh-rsa',
746 ('n', 'e', 'd', 'p', 'q', 'u'): 'ssh-rsa',
747 ('y', 'g', 'p', 'q', 'x'): 'ssh-dss'
748 }
749 try:
750 return keyDataMapping[tuple(obj.keydata)]
751 except (KeyError, AttributeError):
752 raise BadKeyError("invalid key object", obj)
753
754 def pkcs1Pad(data, messageLength):
755 """
756 Pad out data to messageLength according to the PKCS#1 standard.
757 @type data: C{str}
758 @type messageLength: C{int}
759 """
760 lenPad = messageLength - 2 - len(data)
761 return '\x01' + ('\xff' * lenPad) + '\x00' + data
762
763 def pkcs1Digest(data, messageLength):
764 """
765 Create a message digest using the SHA1 hash algorithm according to the
766 PKCS#1 standard.
767 @type data: C{str}
768 @type messageLength: C{str}
769 """
770 digest = sha.new(data).digest()
771 return pkcs1Pad(ID_SHA1+digest, messageLength)
772
773 def lenSig(obj):
774 """
775 Return the length of the signature in bytes for a key object.
776
777 @type obj: C{Crypto.PublicKey.pubkey.pubkey}
778 @rtype: C{long}
779 """
780 return obj.size()/8
781
782 def signData(obj, data):
783 """
784 Sign the data with the given C{Crypto.PublicKey.pubkey.pubkey} object.
785
786 This method is deprecated since Twisted Conch 0.9. Instead use
787 Key().sign().
788
789 @type obj: C{Crypto.PublicKey.pubkey.pubkey}
790 @type data: C{str}
791 @rtype: C{str}
792 """
793 warnings.warn("signData is deprecated since Twisted Conch 0.9."
794 " Use Key(obj).sign(data).",
795 DeprecationWarning, stacklevel=2)
796 return Key(obj).sign(data)
797
798 def verifySignature(obj, sig, data):
799 """
800 Verify that the signature for the data is valid.
801
802 This method is deprecated since Twisted Conch 0.9. Use
803 Key().verify().
804
805 @type obj: C{Crypto.PublicKey.pubkey.pubkey}
806 @type sig: C{str}
807 @type data: C{str}
808 @rtype: C{bool}
809 """
810 warnings.warn("verifySignature is deprecated since Twisted Conch 0.9."
811 " Use Key(obj).verify(signature, data).",
812 DeprecationWarning, stacklevel=2)
813 return Key(obj).verify(sig, data)
814
815 def printKey(obj):
816 """
817 Pretty print a C{Crypto.PublicKey.pubkey.pubkey} object.
818
819 This function is deprecated since Twisted Conch 0.9. Use
820 repr(Key()).
821
822 @type obj: C{Crypto.PublicKey.pubkey.pubkey}
823 """
824 warnings.warn("printKey is deprecated since Twisted Conch 0.9."
825 " Use repr(Key(obj)).",
826 DeprecationWarning, stacklevel=2)
827 return repr(Key(obj))[1:-1]
828
829 ID_SHA1 = '\x30\x21\x30\x09\x06\x05\x2b\x0e\x03\x02\x1a\x05\x00\x04\x14'
OLDNEW
« no previous file with comments | « third_party/twisted_8_1/twisted/conch/ssh/forwarding.py ('k') | third_party/twisted_8_1/twisted/conch/ssh/service.py » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698