##// END OF EJS Templates
ssh: replaced pycrypto with cryptography to generate SSH keys....
marcink -
r3520:d8bf39a6 default
parent child Browse files
Show More
@@ -1,123 +1,136 b''
1 1 # -*- coding: utf-8 -*-
2 2
3 3 # Copyright (C) 2013-2019 RhodeCode GmbH
4 4 #
5 5 # This program is free software: you can redistribute it and/or modify
6 6 # it under the terms of the GNU Affero General Public License, version 3
7 7 # (only), as published by the Free Software Foundation.
8 8 #
9 9 # This program is distributed in the hope that it will be useful,
10 10 # but WITHOUT ANY WARRANTY; without even the implied warranty of
11 11 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 12 # GNU General Public License for more details.
13 13 #
14 14 # You should have received a copy of the GNU Affero General Public License
15 15 # along with this program. If not, see <http://www.gnu.org/licenses/>.
16 16 #
17 17 # This program is dual-licensed. If you wish to learn more about the
18 18 # RhodeCode Enterprise Edition, including its added features, Support services,
19 19 # and proprietary license terms, please see https://rhodecode.com/licenses/
20 20
21 21 import logging
22 22 import traceback
23 23
24 24 import sshpubkeys
25 25 import sshpubkeys.exceptions
26 26
27 from cryptography.hazmat.primitives.asymmetric import rsa
28 from cryptography.hazmat.primitives import serialization as crypto_serialization
29 from cryptography.hazmat.backends import default_backend as crypto_default_backend
30
27 31 from rhodecode.model import BaseModel
28 32 from rhodecode.model.db import UserSshKeys
29 33 from rhodecode.model.meta import Session
30 34
35
31 36 log = logging.getLogger(__name__)
32 37
33 38
34 39 class SshKeyModel(BaseModel):
35 40 cls = UserSshKeys
36 41
37 42 def parse_key(self, key_data):
38 43 """
39 44 print(ssh.bits) # 768
40 45 print(ssh.hash_md5()) # 56:84:1e:90:08:3b:60:c7:29:70:5f:5e:25:a6:3b:86
41 46 print(ssh.hash_sha256()) # SHA256:xk3IEJIdIoR9MmSRXTP98rjDdZocmXJje/28ohMQEwM
42 47 print(ssh.hash_sha512()) # SHA512:1C3lNBhjpDVQe39hnyy+xvlZYU3IPwzqK1rVneGavy6O3/ebjEQSFvmeWoyMTplIanmUK1hmr9nA8Skmj516HA
43 48 print(ssh.comment) # ojar@ojar-laptop
44 49 print(ssh.options_raw) # None (string of optional options at the beginning of public key)
45 50 print(ssh.options) # None (options as a dictionary, parsed and validated)
46 51
47 52 :param key_data:
48 53 :return:
49 54 """
50 55 ssh = sshpubkeys.SSHKey(strict_mode=True)
51 56 try:
52 57 ssh.parse(key_data)
53 58 return ssh
54 59 except sshpubkeys.exceptions.InvalidKeyException as err:
55 60 log.error("Invalid key: %s", err)
56 61 raise
57 62 except NotImplementedError as err:
58 63 log.error("Invalid key type: %s", err)
59 64 raise
60 65 except Exception as err:
61 66 log.error("Key Parse error: %s", err)
62 67 raise
63 68
64 69 def generate_keypair(self, comment=None):
65 from Crypto.PublicKey import RSA
66
67 key = RSA.generate(2048)
68 private = key.exportKey('PEM')
69 70
70 pubkey = key.publickey()
71 public = pubkey.exportKey('OpenSSH')
71 key = rsa.generate_private_key(
72 backend=crypto_default_backend(),
73 public_exponent=65537,
74 key_size=2048
75 )
76 private_key = key.private_bytes(
77 crypto_serialization.Encoding.PEM,
78 crypto_serialization.PrivateFormat.PKCS8,
79 crypto_serialization.NoEncryption())
80 public_key = key.public_key().public_bytes(
81 crypto_serialization.Encoding.OpenSSH,
82 crypto_serialization.PublicFormat.OpenSSH
83 )
84
72 85 if comment:
73 public = public + " " + comment
74 return private, public
86 public_key = public_key + " " + comment
87 return private_key, public_key
75 88
76 89 def create(self, user, fingerprint, key_data, description):
77 90 """
78 91 """
79 92 user = self._get_user(user)
80 93
81 94 new_ssh_key = UserSshKeys()
82 95 new_ssh_key.ssh_key_fingerprint = fingerprint
83 96 new_ssh_key.ssh_key_data = key_data
84 97 new_ssh_key.user_id = user.user_id
85 98 new_ssh_key.description = description
86 99
87 100 Session().add(new_ssh_key)
88 101
89 102 return new_ssh_key
90 103
91 104 def delete(self, ssh_key_id, user=None):
92 105 """
93 106 Deletes given api_key, if user is set it also filters the object for
94 107 deletion by given user.
95 108 """
96 109 ssh_key = UserSshKeys.query().filter(
97 110 UserSshKeys.ssh_key_id == ssh_key_id)
98 111
99 112 if user:
100 113 user = self._get_user(user)
101 114 ssh_key = ssh_key.filter(UserSshKeys.user_id == user.user_id)
102 115 ssh_key = ssh_key.scalar()
103 116
104 117 if ssh_key:
105 118 try:
106 119 Session().delete(ssh_key)
107 120 except Exception:
108 121 log.error(traceback.format_exc())
109 122 raise
110 123
111 124 def get_ssh_keys(self, user):
112 125 user = self._get_user(user)
113 126 user_ssh_keys = UserSshKeys.query()\
114 127 .filter(UserSshKeys.user_id == user.user_id)
115 128 user_ssh_keys = user_ssh_keys.order_by(UserSshKeys.ssh_key_id)
116 129 return user_ssh_keys
117 130
118 131 def get_ssh_key_by_fingerprint(self, ssh_key_fingerprint):
119 132 user_ssh_key = UserSshKeys.query()\
120 133 .filter(UserSshKeys.ssh_key_fingerprint == ssh_key_fingerprint)\
121 134 .first()
122 135
123 136 return user_ssh_key
General Comments 0
You need to be logged in to leave comments. Login now