1
# -*- test-case-name: twisted.conch.test.test_keys -*-
2
# Copyright (c) 2001-2010 Twisted Matrix Laboratories.
3
# See LICENSE for details.
6
Handling of RSA and DSA keys.
8
Maintainer: U{Paul Swartz}
11
# base library imports
16
# external library imports
17
from Crypto.Cipher import DES3
18
from Crypto.PublicKey import RSA, DSA
19
from Crypto import Util
20
from pyasn1.type import univ
21
from pyasn1.codec.ber import decoder as berDecoder
22
from pyasn1.codec.ber import encoder as berEncoder
25
from twisted.python import randbytes
26
from twisted.python.hashlib import md5, sha1
29
from twisted.conch.ssh import common, sexpy
32
class BadKeyError(Exception):
34
Raised when a key isn't what we expected from it.
36
XXX: we really need to check for bad keys
39
class EncryptedKeyError(Exception):
41
Raised when an encrypted key is presented to fromString/fromFile without
47
An object representing a key. A key can be either a public or
48
private key. A public key can verify a signature; a private key can
49
create or verify a signature. To generate a string that can be stored
50
on disk, use the toString method. If you have a private key, but want
51
the string representation of the public key, use Key.public().toString().
53
@ivar keyObject: The C{Crypto.PublicKey.pubkey.pubkey} object that
54
operations are performed with.
57
def fromFile(Class, filename, type=None, passphrase=None):
59
Return a Key object corresponding to the data in filename. type
60
and passphrase function as they do in fromString.
62
return Class.fromString(file(filename, 'rb').read(), type, passphrase)
63
fromFile = classmethod(fromFile)
65
def fromString(Class, data, type=None, passphrase=None):
67
Return a Key object corresponding to the string data.
68
type is optionally the type of string, matching a _fromString_*
69
method. Otherwise, the _guessStringType() classmethod will be used
70
to guess a type. If the key is encrypted, passphrase is used as
74
@type type: C{None}/C{str}
75
@type passphrase: C{None}/C{str}
79
type = Class._guessStringType(data)
81
raise BadKeyError('cannot guess the type of %r' % data)
82
method = getattr(Class, '_fromString_%s' % type.upper(), None)
84
raise BadKeyError('no _fromString method for %s' % type)
85
if method.func_code.co_argcount == 2: # no passphrase
87
raise BadKeyError('key not encrypted')
90
return method(data, passphrase)
91
fromString = classmethod(fromString)
93
def _fromString_BLOB(Class, blob):
95
Return a public key object corresponding to this public key blob.
96
The format of a RSA public key blob is::
101
The format of a DSA public key blob is::
109
@return: a C{Crypto.PublicKey.pubkey.pubkey} object
110
@raises BadKeyError: if the key type (the first string) is unknown.
112
keyType, rest = common.getNS(blob)
113
if keyType == 'ssh-rsa':
114
e, n, rest = common.getMP(rest, 2)
115
return Class(RSA.construct((n, e)))
116
elif keyType == 'ssh-dss':
117
p, q, g, y, rest = common.getMP(rest, 4)
118
return Class(DSA.construct((y, g, p, q)))
120
raise BadKeyError('unknown blob type: %s' % keyType)
121
_fromString_BLOB = classmethod(_fromString_BLOB)
123
def _fromString_PRIVATE_BLOB(Class, blob):
125
Return a private key object corresponding to this private key blob.
126
The blob formats are as follows:
146
@return: a C{Crypto.PublicKey.pubkey.pubkey} object
147
@raises BadKeyError: if the key type (the first string) is unknown.
149
keyType, rest = common.getNS(blob)
151
if keyType == 'ssh-rsa':
152
n, e, d, u, p, q, rest = common.getMP(rest, 6)
153
rsakey = Class(RSA.construct((n, e, d, p, q, u)))
155
elif keyType == 'ssh-dss':
156
p, q, g, y, x, rest = common.getMP(rest, 5)
157
dsakey = Class(DSA.construct((y, g, p, q, x)))
160
raise BadKeyError('unknown blob type: %s' % keyType)
161
_fromString_PRIVATE_BLOB = classmethod(_fromString_PRIVATE_BLOB)
163
def _fromString_PUBLIC_OPENSSH(Class, data):
165
Return a public key object corresponding to this OpenSSH public key
166
string. The format of an OpenSSH public key string is::
167
<key type> <base64-encoded public key blob>
170
@return: A {Crypto.PublicKey.pubkey.pubkey} object
171
@raises BadKeyError: if the blob type is unknown.
173
blob = base64.decodestring(data.split()[1])
174
return Class._fromString_BLOB(blob)
175
_fromString_PUBLIC_OPENSSH = classmethod(_fromString_PUBLIC_OPENSSH)
177
def _fromString_PRIVATE_OPENSSH(Class, data, passphrase):
179
Return a private key object corresponding to this OpenSSH private key
180
string. If the key is encrypted, passphrase MUST be provided.
181
Providing a passphrase for an unencrypted key is an error.
183
The format of an OpenSSH private key string is::
184
-----BEGIN <key type> PRIVATE KEY-----
185
[Proc-Type: 4,ENCRYPTED
186
DEK-Info: DES-EDE3-CBC,<initialization value>]
187
<base64-encoded ASN.1 structure>
188
------END <key type> PRIVATE KEY------
190
The ASN.1 structure of a RSA key is::
193
The ASN.1 structure of a DSA key is::
197
@type passphrase: C{str}
198
@return: a C{Crypto.PublicKey.pubkey.pubkey} object
199
@raises BadKeyError: if
200
* a passphrase is provided for an unencrypted key
201
* a passphrase is not provided for an encrypted key
202
* the ASN.1 encoding is incorrect
204
lines = [x + '\n' for x in data.split('\n')]
205
kind = lines[0][11:14]
206
if lines[1].startswith('Proc-Type: 4,ENCRYPTED'): # encrypted key
207
ivdata = lines[2].split(',')[1][:-1]
208
iv = ''.join([chr(int(ivdata[i:i + 2], 16)) for i in range(0,
211
raise EncryptedKeyError('encrypted key with no passphrase')
212
ba = md5(passphrase + iv).digest()
213
bb = md5(ba + passphrase + iv).digest()
214
decKey = (ba + bb)[:24]
215
b64Data = base64.decodestring(''.join(lines[3:-1]))
216
keyData = DES3.new(decKey, DES3.MODE_CBC, iv).decrypt(b64Data)
217
removeLen = ord(keyData[-1])
218
keyData = keyData[:-removeLen]
220
b64Data = ''.join(lines[1:-1])
221
keyData = base64.decodestring(b64Data)
223
decodedKey = berDecoder.decode(keyData)[0]
225
raise BadKeyError, 'something wrong with decode'
227
if len(decodedKey) == 2: # alternate RSA key
228
decodedKey = decodedKey[0]
229
if len(decodedKey) < 6:
230
raise BadKeyError('RSA key failed to decode properly')
231
n, e, d, p, q = [long(value) for value in decodedKey[1:6]]
232
if p > q: # make p smaller than q
234
return Class(RSA.construct((n, e, d, p, q)))
236
p, q, g, y, x = [long(value) for value in decodedKey[1: 6]]
237
if len(decodedKey) < 6:
238
raise BadKeyError('DSA key failed to decode properly')
239
return Class(DSA.construct((y, g, p, q, x)))
240
_fromString_PRIVATE_OPENSSH = classmethod(_fromString_PRIVATE_OPENSSH)
242
def _fromString_PUBLIC_LSH(Class, data):
244
Return a public key corresponding to this LSH public key string.
245
The LSH public key string format is::
246
<s-expression: ('public-key', (<key type>, (<name, <value>)+))>
248
The names for a RSA (key type 'rsa-pkcs1-sha1') key are: n, e.
249
The names for a DSA (key type 'dsa') key are: y, g, p, q.
252
@return: a C{Crypto.PublicKey.pubkey.pubkey} object
253
@raises BadKeyError: if the key type is unknown
255
sexp = sexpy.parse(base64.decodestring(data[1:-1]))
256
assert sexp[0] == 'public-key'
258
for name, data in sexp[1][1:]:
259
kd[name] = common.getMP(common.NS(data))[0]
260
if sexp[1][0] == 'dsa':
261
return Class(DSA.construct((kd['y'], kd['g'], kd['p'], kd['q'])))
262
elif sexp[1][0] == 'rsa-pkcs1-sha1':
263
return Class(RSA.construct((kd['n'], kd['e'])))
265
raise BadKeyError('unknown lsh key type %s' % sexp[1][0])
266
_fromString_PUBLIC_LSH = classmethod(_fromString_PUBLIC_LSH)
268
def _fromString_PRIVATE_LSH(Class, data):
270
Return a private key corresponding to this LSH private key string.
271
The LSH private key string format is::
272
<s-expression: ('private-key', (<key type>, (<name>, <value>)+))>
274
The names for a RSA (key type 'rsa-pkcs1-sha1') key are: n, e, d, p, q.
275
The names for a DSA (key type 'dsa') key are: y, g, p, q, x.
278
@return: a {Crypto.PublicKey.pubkey.pubkey} object
279
@raises BadKeyError: if the key type is unknown
281
sexp = sexpy.parse(data)
282
assert sexp[0] == 'private-key'
284
for name, data in sexp[1][1:]:
285
kd[name] = common.getMP(common.NS(data))[0]
286
if sexp[1][0] == 'dsa':
287
assert len(kd) == 5, len(kd)
288
return Class(DSA.construct((kd['y'], kd['g'], kd['p'],
290
elif sexp[1][0] == 'rsa-pkcs1':
291
assert len(kd) == 8, len(kd)
292
if kd['p'] > kd['q']: # make p smaller than q
293
kd['p'], kd['q'] = kd['q'], kd['p']
294
return Class(RSA.construct((kd['n'], kd['e'], kd['d'],
297
raise BadKeyError('unknown lsh key type %s' % sexp[1][0])
298
_fromString_PRIVATE_LSH = classmethod(_fromString_PRIVATE_LSH)
300
def _fromString_AGENTV3(Class, data):
302
Return a private key object corresponsing to the Secure Shell Key
305
The SSH Key Agent v3 format for a RSA key is::
314
The SSH Key Agent v3 format for a DSA key is::
323
@return: a C{Crypto.PublicKey.pubkey.pubkey} object
324
@raises BadKeyError: if the key type (the first string) is unknown
326
keyType, data = common.getNS(data)
327
if keyType == 'ssh-dss':
328
p, data = common.getMP(data)
329
q, data = common.getMP(data)
330
g, data = common.getMP(data)
331
y, data = common.getMP(data)
332
x, data = common.getMP(data)
333
return Class(DSA.construct((y,g,p,q,x)))
334
elif keyType == 'ssh-rsa':
335
e, data = common.getMP(data)
336
d, data = common.getMP(data)
337
n, data = common.getMP(data)
338
u, data = common.getMP(data)
339
p, data = common.getMP(data)
340
q, data = common.getMP(data)
341
return Class(RSA.construct((n,e,d,p,q,u)))
343
raise BadKeyError("unknown key type %s" % keyType)
344
_fromString_AGENTV3 = classmethod(_fromString_AGENTV3)
346
def _guessStringType(Class, data):
348
Guess the type of key in data. The types map to _fromString_*
351
if data.startswith('ssh-'):
352
return 'public_openssh'
353
elif data.startswith('-----BEGIN'):
354
return 'private_openssh'
355
elif data.startswith('{'):
357
elif data.startswith('('):
359
elif data.startswith('\x00\x00\x00\x07ssh-'):
360
ignored, rest = common.getNS(data)
364
ignored, rest = common.getMP(rest)
369
_guessStringType = classmethod(_guessStringType)
371
def __init__(self, keyObject):
373
Initialize a PublicKey with a C{Crypto.PublicKey.pubkey.pubkey}
376
@type keyObject: C{Crypto.PublicKey.pubkey.pubkey}
378
self.keyObject = keyObject
380
def __eq__(self, other):
382
Return True if other represents an object with the same key.
384
if type(self) == type(other):
385
return self.type() == other.type() and self.data() == other.data()
387
return NotImplemented
389
def __ne__(self, other):
391
Return True if other represents anything other than this key.
393
result = self.__eq__(other)
394
if result == NotImplemented:
400
Return a pretty representation of this object.
402
lines = ['<%s %s (%s bits)' % (self.type(),
403
self.isPublic() and 'Public Key' or 'Private Key',
404
self.keyObject.size())]
405
for k, v in self.data().items():
406
lines.append('attr %s:' % k)
407
by = common.MP(v)[4:]
413
o = o + '%02x:' % ord(c)
416
lines.append('\t' + o)
417
lines[-1] = lines[-1] + '>'
418
return '\n'.join(lines)
422
Returns True if this Key is a public key.
424
return not self.keyObject.has_private()
428
Returns a version of this key containing only the public key data.
429
If this is a public key, this may or may not be the same object
432
return Key(self.keyObject.publickey())
435
def fingerprint(self):
437
Get the user presentation of the fingerprint of this L{Key}. As
438
described by U{RFC 4716 section
439
4<http://tools.ietf.org/html/rfc4716#section-4>}::
441
The fingerprint of a public key consists of the output of the MD5
442
message-digest algorithm [RFC1321]. The input to the algorithm is
443
the public key data as specified by [RFC4253]. (...) The output
444
of the (MD5) algorithm is presented to the user as a sequence of 16
445
octets printed as hexadecimal with lowercase letters and separated
450
@return: the user presentation of this L{Key}'s fingerprint, as a
455
return ':'.join([x.encode('hex') for x in md5(self.blob()).digest()])
460
Return the type of the object we wrap. Currently this can only be
463
# the class is Crypto.PublicKey.<type>.<stuff we don't care about>
464
klass = str(self.keyObject.__class__)
465
if klass.startswith('Crypto.PublicKey'):
466
type = klass.split('.')[2]
468
raise RuntimeError('unknown type of object: %r' % self.keyObject)
469
if type in ('RSA', 'DSA'):
472
raise RuntimeError('unknown type of key: %s' % type)
476
Return the type of the object we wrap as defined in the ssh protocol.
477
Currently this can only be 'ssh-rsa' or 'ssh-dss'.
479
return {'RSA':'ssh-rsa', 'DSA':'ssh-dss'}[self.type()]
483
Return the values of the public key as a dictionary.
488
for name in self.keyObject.keydata:
489
value = getattr(self.keyObject, name, None)
490
if value is not None:
491
keyData[name] = value
496
Return the public key blob for this key. The blob is the
497
over-the-wire format for public keys:
516
return (common.NS('ssh-rsa') + common.MP(data['e']) +
517
common.MP(data['n']))
519
return (common.NS('ssh-dss') + common.MP(data['p']) +
520
common.MP(data['q']) + common.MP(data['g']) +
521
common.MP(data['y']))
523
def privateBlob(self):
525
Return the private key blob for this key. The blob is the
526
over-the-wire format for private keys:
548
return (common.NS('ssh-rsa') + common.MP(data['n']) +
549
common.MP(data['e']) + common.MP(data['d']) +
550
common.MP(data['u']) + common.MP(data['p']) +
551
common.MP(data['q']))
553
return (common.NS('ssh-dss') + common.MP(data['p']) +
554
common.MP(data['q']) + common.MP(data['g']) +
555
common.MP(data['y']) + common.MP(data['x']))
557
def toString(self, type, extra=None):
559
Create a string representation of this key. If the key is a private
560
key and you want the represenation of its public key, use
561
C{key.public().toString()}. type maps to a _toString_* method.
563
@param type: The type of string to emit. Currently supported values
564
are C{'OPENSSH'}, C{'LSH'}, and C{'AGENTV3'}.
567
@param extra: Any extra data supported by the selected format which
568
is not part of the key itself. For public OpenSSH keys, this is
569
a comment. For private OpenSSH keys, this is a passphrase to
571
@type extra: L{str} or L{NoneType}
575
method = getattr(self, '_toString_%s' % type.upper(), None)
577
raise BadKeyError('unknown type: %s' % type)
578
if method.func_code.co_argcount == 2:
583
def _toString_OPENSSH(self, extra):
585
Return a public or private OpenSSH string. See
586
_fromString_PUBLIC_OPENSSH and _fromString_PRIVATE_OPENSSH for the
587
string formats. If extra is present, it represents a comment for a
588
public key, or a passphrase for a private key.
595
b64Data = base64.encodestring(self.blob()).replace('\n', '')
598
return ('%s %s %s' % (self.sshType(), b64Data, extra)).strip()
600
lines = ['-----BEGIN %s PRIVATE KEY-----' % self.type()]
601
if self.type() == 'RSA':
602
p, q = data['p'], data['q']
603
objData = (0, data['n'], data['e'], data['d'], q, p,
604
data['d'] % (q - 1), data['d'] % (p - 1),
607
objData = (0, data['p'], data['q'], data['g'], data['y'],
609
asn1Sequence = univ.Sequence()
610
for index, value in itertools.izip(itertools.count(), objData):
611
asn1Sequence.setComponentByPosition(index, univ.Integer(value))
612
asn1Data = berEncoder.encode(asn1Sequence)
614
iv = randbytes.secureRandom(8)
615
hexiv = ''.join(['%02X' % ord(x) for x in iv])
616
lines.append('Proc-Type: 4,ENCRYPTED')
617
lines.append('DEK-Info: DES-EDE3-CBC,%s\n' % hexiv)
618
ba = md5(extra + iv).digest()
619
bb = md5(ba + extra + iv).digest()
620
encKey = (ba + bb)[:24]
621
padLen = 8 - (len(asn1Data) % 8)
622
asn1Data += (chr(padLen) * padLen)
623
asn1Data = DES3.new(encKey, DES3.MODE_CBC,
624
iv).encrypt(asn1Data)
625
b64Data = base64.encodestring(asn1Data).replace('\n', '')
626
lines += [b64Data[i:i + 64] for i in range(0, len(b64Data), 64)]
627
lines.append('-----END %s PRIVATE KEY-----' % self.type())
628
return '\n'.join(lines)
630
def _toString_LSH(self):
632
Return a public or private LSH key. See _fromString_PUBLIC_LSH and
633
_fromString_PRIVATE_LSH for the key formats.
639
if self.type() == 'RSA':
640
keyData = sexpy.pack([['public-key', ['rsa-pkcs1-sha1',
641
['n', common.MP(data['n'])[4:]],
642
['e', common.MP(data['e'])[4:]]]]])
643
elif self.type() == 'DSA':
644
keyData = sexpy.pack([['public-key', ['dsa',
645
['p', common.MP(data['p'])[4:]],
646
['q', common.MP(data['q'])[4:]],
647
['g', common.MP(data['g'])[4:]],
648
['y', common.MP(data['y'])[4:]]]]])
649
return '{' + base64.encodestring(keyData).replace('\n', '') + '}'
651
if self.type() == 'RSA':
652
p, q = data['p'], data['q']
653
return sexpy.pack([['private-key', ['rsa-pkcs1',
654
['n', common.MP(data['n'])[4:]],
655
['e', common.MP(data['e'])[4:]],
656
['d', common.MP(data['d'])[4:]],
657
['p', common.MP(q)[4:]],
658
['q', common.MP(p)[4:]],
659
['a', common.MP(data['d'] % (q - 1))[4:]],
660
['b', common.MP(data['d'] % (p - 1))[4:]],
661
['c', common.MP(data['u'])[4:]]]]])
662
elif self.type() == 'DSA':
663
return sexpy.pack([['private-key', ['dsa',
664
['p', common.MP(data['p'])[4:]],
665
['q', common.MP(data['q'])[4:]],
666
['g', common.MP(data['g'])[4:]],
667
['y', common.MP(data['y'])[4:]],
668
['x', common.MP(data['x'])[4:]]]]])
670
def _toString_AGENTV3(self):
672
Return a private Secure Shell Agent v3 key. See
673
_fromString_AGENTV3 for the key format.
678
if not self.isPublic():
679
if self.type() == 'RSA':
680
values = (data['e'], data['d'], data['n'], data['u'],
681
data['p'], data['q'])
682
elif self.type() == 'DSA':
683
values = (data['p'], data['q'], data['g'], data['y'],
685
return common.NS(self.sshType()) + ''.join(map(common.MP, values))
688
def sign(self, data):
690
Returns a signature with this Key.
695
if self.type() == 'RSA':
696
digest = pkcs1Digest(data, self.keyObject.size()/8)
697
signature = self.keyObject.sign(digest, '')[0]
698
ret = common.NS(Util.number.long_to_bytes(signature))
699
elif self.type() == 'DSA':
700
digest = sha1(data).digest()
701
randomBytes = randbytes.secureRandom(19)
702
sig = self.keyObject.sign(digest, randomBytes)
703
# SSH insists that the DSS signature blob be two 160-bit integers
704
# concatenated together. The sig[0], [1] numbers from obj.sign
705
# are just numbers, and could be any length from 0 to 160 bits.
706
# Make sure they are padded out to 160 bits (20 bytes each)
707
ret = common.NS(Util.number.long_to_bytes(sig[0], 20) +
708
Util.number.long_to_bytes(sig[1], 20))
709
return common.NS(self.sshType()) + ret
711
def verify(self, signature, data):
713
Returns true if the signature for data is valid for this Key.
715
@type signature: C{str}
719
signatureType, signature = common.getNS(signature)
720
if signatureType != self.sshType():
722
if self.type() == 'RSA':
723
numbers = common.getMP(signature)
724
digest = pkcs1Digest(data, self.keyObject.size() / 8)
725
elif self.type() == 'DSA':
726
signature = common.getNS(signature)[0]
727
numbers = [Util.number.bytes_to_long(n) for n in signature[:20],
729
digest = sha1(data).digest()
730
return self.keyObject.verify(digest, numbers)
732
def getPublicKeyString(filename=None, line=0, data=''):
734
Return a public key string suitable for being sent over the wire.
735
Takes a filename or data of a public key. Currently handles OpenSSH
738
This function has been deprecated since Twisted Conch 0.9. Use
739
Key.fromString() instead.
741
@type filename: C{str}
746
warnings.warn("getPublicKeyString is deprecated since Twisted Conch 0.9."
747
" Use Key.fromString().blob().",
748
DeprecationWarning, stacklevel=2)
749
if filename and data:
750
raise BadKeyError("either filename or data, not both")
752
lines = open(filename).readlines()
754
return Key.fromString(data).blob()
756
def makePublicKeyString(obj, comment='', kind='openssh'):
758
Return an public key given a C{Crypto.PublicKey.pubkey.pubkey}
760
kind is one of ('openssh', 'lsh')
762
This function is deprecated since Twisted Conch 0.9. Instead use
765
@type obj: C{Crypto.PublicKey.pubkey.pubkey}
766
@type comment: C{str}
770
warnings.warn("makePublicKeyString is deprecated since Twisted Conch 0.9."
771
" Use Key(obj).public().toString().",
772
DeprecationWarning, stacklevel=2)
773
return Key(obj).public().toString(kind, comment)
775
def getPublicKeyObject(data):
777
Return a C{Crypto.PublicKey.pubkey.pubkey} corresponding to the SSHv2
778
public key data. data is in the over-the-wire public key format.
780
This function is deprecated since Twisted Conch 0.9. Instead, use
784
@rtype: C{Crypto.PublicKey.pubkey.pubkey}
786
warnings.warn("getPublicKeyObject is deprecated since Twisted Conch 0.9."
787
" Use Key.fromString().",
788
DeprecationWarning, stacklevel=2)
789
return Key.fromString(data).keyObject
791
def getPrivateKeyObject(filename=None, data='', passphrase=''):
793
Return a C{Crypto.PublicKey.pubkey.pubkey} object corresponding to the
794
private key file/data. If the private key is encrypted, passphrase B{must}
795
be specified, other wise a L{BadKeyError} will be raised.
797
This method is deprecated since Twisted Conch 0.9. Instead, use
798
the fromString or fromFile classmethods of Key.
800
@type filename: C{str}
802
@type passphrase: C{str}
803
@rtype: C{Crypto.PublicKey.pubkey.pubkey}
804
@raises BadKeyError: if the key is invalid or a passphrase is not specified
806
warnings.warn("getPrivateKeyObject is deprecated since Twisted Conch 0.9."
807
" Use Key.fromString().",
808
DeprecationWarning, stacklevel=2)
809
if filename and data:
810
raise BadKeyError("either filename or data, not both")
812
return Key.fromFile(filename, passphrase=passphrase).keyObject
814
return Key.fromString(data, passphrase=passphrase).keyObject
816
def makePrivateKeyString(obj, passphrase=None, kind='openssh'):
818
Return an OpenSSH-style private key for a
819
C{Crypto.PublicKey.pubkey.pubkey} object. If passphrase is given, encrypt
820
the private key with it.
821
kind is one of ('openssh', 'lsh', 'agentv3')
823
This function is deprecated since Twisted Conch 0.9. Instead use
826
@type obj: C{Crypto.PublicKey.pubkey.pubkey}
827
@type passphrase: C{str}/C{None}
831
warnings.warn("makePrivateKeyString is deprecated since Twisted Conch 0.9."
832
" Use Key(obj).toString().",
833
DeprecationWarning, stacklevel=2)
834
return Key(obj).toString(kind, passphrase)
836
def makePublicKeyBlob(obj):
838
Make a public key blob from a C{Crypto.PublicKey.pubkey.pubkey}.
840
This function is deprecated since Twisted Conch 0.9. Use
841
Key().blob() instead.
843
warnings.warn("makePublicKeyBlob is deprecated since Twisted Conch 0.9."
844
" Use Key(obj).blob().",
845
DeprecationWarning, stacklevel=2)
846
return Key(obj).blob()
850
Return the SSH key type corresponding to a C{Crypto.PublicKey.pubkey.pubkey}
853
@type obj: C{Crypto.PublicKey.pubkey.pubkey}
857
('n', 'e', 'd', 'p', 'q'): 'ssh-rsa',
858
('n', 'e', 'd', 'p', 'q', 'u'): 'ssh-rsa',
859
('y', 'g', 'p', 'q', 'x'): 'ssh-dss'
862
return keyDataMapping[tuple(obj.keydata)]
863
except (KeyError, AttributeError):
864
raise BadKeyError("invalid key object", obj)
866
def pkcs1Pad(data, messageLength):
868
Pad out data to messageLength according to the PKCS#1 standard.
870
@type messageLength: C{int}
872
lenPad = messageLength - 2 - len(data)
873
return '\x01' + ('\xff' * lenPad) + '\x00' + data
875
def pkcs1Digest(data, messageLength):
877
Create a message digest using the SHA1 hash algorithm according to the
880
@type messageLength: C{str}
882
digest = sha1(data).digest()
883
return pkcs1Pad(ID_SHA1+digest, messageLength)
887
Return the length of the signature in bytes for a key object.
889
@type obj: C{Crypto.PublicKey.pubkey.pubkey}
894
def signData(obj, data):
896
Sign the data with the given C{Crypto.PublicKey.pubkey.pubkey} object.
898
This method is deprecated since Twisted Conch 0.9. Instead use
901
@type obj: C{Crypto.PublicKey.pubkey.pubkey}
905
warnings.warn("signData is deprecated since Twisted Conch 0.9."
906
" Use Key(obj).sign(data).",
907
DeprecationWarning, stacklevel=2)
908
return Key(obj).sign(data)
910
def verifySignature(obj, sig, data):
912
Verify that the signature for the data is valid.
914
This method is deprecated since Twisted Conch 0.9. Use
917
@type obj: C{Crypto.PublicKey.pubkey.pubkey}
922
warnings.warn("verifySignature is deprecated since Twisted Conch 0.9."
923
" Use Key(obj).verify(signature, data).",
924
DeprecationWarning, stacklevel=2)
925
return Key(obj).verify(sig, data)
929
Pretty print a C{Crypto.PublicKey.pubkey.pubkey} object.
931
This function is deprecated since Twisted Conch 0.9. Use
934
@type obj: C{Crypto.PublicKey.pubkey.pubkey}
936
warnings.warn("printKey is deprecated since Twisted Conch 0.9."
937
" Use repr(Key(obj)).",
938
DeprecationWarning, stacklevel=2)
939
return repr(Key(obj))[1:-1]
941
ID_SHA1 = '\x30\x21\x30\x09\x06\x05\x2b\x0e\x03\x02\x1a\x05\x00\x04\x14'