def _toString_OPENSSH(self, extra): """ Return a public or private OpenSSH string. See _fromString_PUBLIC_OPENSSH and _fromString_PRIVATE_OPENSSH for the string formats. If extra is present, it represents a comment for a public key, or a passphrase for a private key. @param extra: Comment for a public key or passphrase for a private key @type extra: L{bytes} @rtype: L{bytes} """ data = self.data() if self.isPublic(): b64Data = encodebytes(self.blob()).replace(b'\n', b'') if not extra: extra = b'' return (self.sshType() + b' ' + b64Data + b' ' + extra).strip() else: lines = [b''.join((b'-----BEGIN ', self.type().encode('ascii'), b' PRIVATE KEY-----'))] if self.type() == 'RSA': p, q = data['p'], data['q'] objData = (0, data['n'], data['e'], data['d'], q, p, data['d'] % (q - 1), data['d'] % (p - 1), data['u']) else: objData = (0, data['p'], data['q'], data['g'], data['y'], data['x']) asn1Sequence = univ.Sequence() for index, value in izip(itertools.count(), objData): asn1Sequence.setComponentByPosition(index, univ.Integer(value)) asn1Data = berEncoder.encode(asn1Sequence) if extra: iv = randbytes.secureRandom(8) hexiv = ''.join(['%02X' % (ord(x),) for x in iterbytes(iv)]) hexiv = hexiv.encode('ascii') lines.append(b'Proc-Type: 4,ENCRYPTED') lines.append(b'DEK-Info: DES-EDE3-CBC,' + hexiv + b'\n') ba = md5(extra + iv).digest() bb = md5(ba + extra + iv).digest() encKey = (ba + bb)[:24] padLen = 8 - (len(asn1Data) % 8) asn1Data += (chr(padLen) * padLen).encode('ascii') encryptor = Cipher( algorithms.TripleDES(encKey), modes.CBC(iv), backend=default_backend() ).encryptor() asn1Data = encryptor.update(asn1Data) + encryptor.finalize() b64Data = encodebytes(asn1Data).replace(b'\n', b'') lines += [b64Data[i:i + 64] for i in range(0, len(b64Data), 64)] lines.append(b''.join((b'-----END ', self.type().encode('ascii'), b' PRIVATE KEY-----'))) return b'\n'.join(lines)
def _toString_LSH(self): """ Return a public or private LSH key. See _fromString_PUBLIC_LSH and _fromString_PRIVATE_LSH for the key formats. @rtype: L{bytes} """ data = self.data() type = self.type() if self.isPublic(): if type == 'RSA': keyData = sexpy.pack([[b'public-key', [b'rsa-pkcs1-sha1', [b'n', common.MP(data['n'])[4:]], [b'e', common.MP(data['e'])[4:]]]]]) elif type == 'DSA': keyData = sexpy.pack([[b'public-key', [b'dsa', [b'p', common.MP(data['p'])[4:]], [b'q', common.MP(data['q'])[4:]], [b'g', common.MP(data['g'])[4:]], [b'y', common.MP(data['y'])[4:]]]]]) else: raise BadKeyError("unknown key type %s" % (type,)) return (b'{' + encodebytes(keyData).replace(b'\n', b'') + b'}') else: if type == 'RSA': p, q = data['p'], data['q'] return sexpy.pack([[b'private-key', [b'rsa-pkcs1', [b'n', common.MP(data['n'])[4:]], [b'e', common.MP(data['e'])[4:]], [b'd', common.MP(data['d'])[4:]], [b'p', common.MP(q)[4:]], [b'q', common.MP(p)[4:]], [b'a', common.MP( data['d'] % (q - 1))[4:]], [b'b', common.MP( data['d'] % (p - 1))[4:]], [b'c', common.MP(data['u'])[4:]]]]]) elif type == 'DSA': return sexpy.pack([[b'private-key', [b'dsa', [b'p', common.MP(data['p'])[4:]], [b'q', common.MP(data['q'])[4:]], [b'g', common.MP(data['g'])[4:]], [b'y', common.MP(data['y'])[4:]], [b'x', common.MP(data['x'])[4:]]]]]) else: raise BadKeyError("unknown key type %s'" % (type,))