forked from ParallelSSH/ssh-python
-
Notifications
You must be signed in to change notification settings - Fork 1
Expand file tree
/
Copy pathkey.pyx
More file actions
244 lines (211 loc) · 7.12 KB
/
key.pyx
File metadata and controls
244 lines (211 loc) · 7.12 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
# This file is part of ssh-python.
# Copyright (C) 2018 Panos Kittenis
#
# This library is free software; you can redistribute it and/or
# modify it under the terms of the GNU Lesser General Public
# License as published by the Free Software Foundation, version 2.1.
#
# This library is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
# Lesser General Public License for more details.
#
# You should have received a copy of the GNU Lesser General Public
# License along with this library; if not, write to the Free Software
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-130
from libc.string cimport const_char
from keytypes cimport from_keytype, KeyType
from utils cimport to_str, to_bytes
from .exceptions import KeyExportError, KeyImportError, KeyGenerationError
cimport c_ssh
cdef class SSHKey:
@staticmethod
cdef SSHKey from_ptr(c_ssh.ssh_key key):
cdef SSHKey _key = SSHKey.__new__(SSHKey)
_key._key = key
return _key
def __cinit__(self):
self._key = c_ssh.ssh_key_new()
if self._key is NULL:
raise MemoryError
def __dealloc__(self):
if self._key is not NULL:
c_ssh.ssh_key_free(self._key)
self._key = NULL
def is_private(self):
cdef bint rc
with nogil:
rc = c_ssh.ssh_key_is_private(self._key)
return bool(rc)
def is_public(self):
cdef bint rc
with nogil:
rc = c_ssh.ssh_key_is_public(self._key)
return bool(rc)
def __eq__(self, SSHKey other):
cdef bint is_private
cdef bint equal
with nogil:
is_private = c_ssh.ssh_key_is_private(self._key)
equal = c_ssh.ssh_key_cmp(
self._key, other._key, c_ssh.ssh_keycmp_e.SSH_KEY_CMP_PRIVATE) \
if is_private else \
c_ssh.ssh_key_cmp(
self._key, other._key,
c_ssh.ssh_keycmp_e.SSH_KEY_CMP_PUBLIC)
return bool(not equal)
def key_type(self):
cdef c_ssh.ssh_keytypes_e _type
if self._key is NULL:
return
_type = c_ssh.ssh_key_type(self._key)
return from_keytype(_type)
def ecdsa_name(self):
cdef const_char *c_name
cdef bytes b_name
with nogil:
c_name = c_ssh.ssh_pki_key_ecdsa_name(self._key)
b_name = c_name
return to_str(b_name)
def export_privkey_file(self, filepath, passphrase=None):
cdef bytes b_passphrase
cdef bytes b_filepath = to_bytes(filepath)
cdef const_char *c_passphrase = NULL
cdef const_char *c_filepath = b_filepath
cdef int rc
if passphrase is not None:
b_passphrase = to_bytes(passphrase)
c_passphrase = b_passphrase
with nogil:
rc = c_ssh.ssh_pki_export_privkey_file(
self._key, c_passphrase, NULL, NULL, c_filepath)
if rc != c_ssh.SSH_OK:
raise KeyExportError
def export_privkey_to_pubkey(self):
cdef SSHKey pub_key
cdef c_ssh.ssh_key _pub_key
cdef int rc
with nogil:
rc = c_ssh.ssh_pki_export_privkey_to_pubkey(self._key, &_pub_key)
if rc != c_ssh.SSH_OK:
raise KeyExportError
pub_key = SSHKey.from_ptr(_pub_key)
return pub_key
def export_pubkey_base64(self):
cdef char *_key
cdef int rc
cdef bytes b_key
cdef size_t key_len
with nogil:
rc = c_ssh.ssh_pki_export_pubkey_base64(self._key, &_key)
if rc != c_ssh.SSH_OK:
with gil:
raise KeyExportError
b_key = _key
c_ssh.ssh_string_free_char(_key)
return b_key
def generate(KeyType key_type, int bits):
cdef SSHKey key
cdef c_ssh.ssh_key _key
cdef int rc
with nogil:
rc = c_ssh.ssh_pki_generate(key_type._type, bits, &_key)
if rc != c_ssh.SSH_OK:
raise KeyGenerationError
key = SSHKey.from_ptr(_key)
return key
def import_privkey_base64(bytes b64_key, passphrase=b''):
cdef const_char *c_key = b64_key
cdef bytes b_passphrase
cdef const_char *c_passphrase = NULL
cdef int rc
cdef SSHKey key
cdef c_ssh.ssh_key _key
if passphrase is not None:
b_passphrase = to_bytes(passphrase)
c_passphrase = b_passphrase
with nogil:
rc = c_ssh.ssh_pki_import_privkey_base64(
c_key, c_passphrase, NULL, NULL, &_key)
if rc != c_ssh.SSH_OK:
raise KeyImportError
key = SSHKey.from_ptr(_key)
return key
def import_privkey_file(filepath, passphrase=b''):
cdef bytes b_passphrase
cdef bytes b_filepath = to_bytes(filepath)
cdef const_char *c_passphrase = NULL
cdef const_char *c_filepath = b_filepath
cdef int rc
cdef SSHKey key
cdef c_ssh.ssh_key _key
if passphrase is not None:
b_passphrase = to_bytes(passphrase)
c_passphrase = b_passphrase
with nogil:
rc = c_ssh.ssh_pki_import_privkey_file(
c_filepath, c_passphrase, NULL, NULL, &_key)
if rc != c_ssh.SSH_OK:
raise KeyImportError
key = SSHKey.from_ptr(_key)
return key
def import_pubkey_base64(bytes b64_key, KeyType key_type):
cdef const_char *c_key = b64_key
cdef int rc
cdef SSHKey key
cdef c_ssh.ssh_key _key
with nogil:
rc = c_ssh.ssh_pki_import_pubkey_base64(
c_key, key_type._type, &_key)
if rc != c_ssh.SSH_OK:
raise KeyImportError
key = SSHKey.from_ptr(_key)
return key
def import_pubkey_file(filepath):
cdef bytes b_filepath = to_bytes(filepath)
cdef const_char *c_filepath = b_filepath
cdef int rc
cdef SSHKey key
cdef c_ssh.ssh_key _key
with nogil:
rc = c_ssh.ssh_pki_import_pubkey_file(
c_filepath, &_key)
if rc != c_ssh.SSH_OK:
raise KeyImportError
key = SSHKey.from_ptr(_key)
return key
def import_cert_base64(bytes b64_cert, KeyType key_type):
cdef const_char *c_key = b64_cert
cdef int rc
cdef SSHKey key
cdef c_ssh.ssh_key _key
with nogil:
rc = c_ssh.ssh_pki_import_cert_base64(
c_key, key_type._type, &_key)
if rc != c_ssh.SSH_OK:
raise KeyImportError
key = SSHKey.from_ptr(_key)
return key
def import_cert_file(filepath):
cdef bytes b_filepath = to_bytes(filepath)
cdef const_char *c_filepath = b_filepath
cdef int rc
cdef SSHKey key
cdef c_ssh.ssh_key _key
with nogil:
rc = c_ssh.ssh_pki_import_cert_file(
c_filepath, &_key)
if rc != c_ssh.SSH_OK:
raise KeyImportError
key = SSHKey.from_ptr(_key)
return key
def copy_cert_to_privkey(SSHKey cert_key, SSHKey priv_key):
if priv_key.is_private() is False:
raise KeyImportError
cdef c_ssh.ssh_key _priv_key = priv_key._key
cdef c_ssh.ssh_key _cert_key = cert_key._key
with nogil:
rc = c_ssh.ssh_pki_copy_cert_to_privkey(
_cert_key, _priv_key)
if rc != c_ssh.SSH_OK:
raise KeyImportError