keepassxc

Форк
0
/
OpenSSHKeyGen.cpp 
141 строка · 5.0 Кб
1
/*
2
 *  Copyright (C) 2021 KeePassXC Team <team@keepassxc.org>
3
 *
4
 *  This program is free software: you can redistribute it and/or modify
5
 *  it under the terms of the GNU General Public License as published by
6
 *  the Free Software Foundation, either version 2 or (at your option)
7
 *  version 3 of the License.
8
 *
9
 *  This program is distributed in the hope that it will be useful,
10
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
11
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
12
 *  GNU General Public License for more details.
13
 *
14
 *  You should have received a copy of the GNU General Public License
15
 *  along with this program.  If not, see <http://www.gnu.org/licenses/>.
16
 */
17

18
#include "OpenSSHKeyGen.h"
19
#include "BinaryStream.h"
20
#include "OpenSSHKey.h"
21
#include "crypto/Random.h"
22

23
#include <botan/ecdsa.h>
24
#include <botan/ed25519.h>
25
#include <botan/rsa.h>
26

27
namespace OpenSSHKeyGen
28
{
29
    namespace
30
    {
31
        void bigIntToStream(const Botan::BigInt& i, BinaryStream& stream, int padding = 0)
32
        {
33
            QByteArray ba(i.bytes() + padding, 0);
34
            i.binary_encode(reinterpret_cast<uint8_t*>(ba.data() + padding), ba.size() - padding);
35
            stream.writeString(ba);
36
        }
37

38
        void vectorToStream(const std::vector<uint8_t>& v, BinaryStream& stream)
39
        {
40
            QByteArray ba(reinterpret_cast<const char*>(v.data()), v.size());
41
            stream.writeString(ba);
42
        }
43

44
        void vectorToStream(const Botan::secure_vector<uint8_t>& v, BinaryStream& stream)
45
        {
46
            QByteArray ba(reinterpret_cast<const char*>(v.data()), v.size());
47
            stream.writeString(ba);
48
        }
49
    } // namespace
50

51
    bool generateRSA(OpenSSHKey& key, int bits)
52
    {
53
        auto rng = randomGen()->getRng();
54

55
        try {
56
            Botan::RSA_PrivateKey rsaKey(*rng, bits);
57

58
            QByteArray publicData;
59
            BinaryStream publicStream(&publicData);
60
            // intentionally flipped n e -> e n
61
            bigIntToStream(rsaKey.get_e(), publicStream);
62
            bigIntToStream(rsaKey.get_n(), publicStream, 1);
63

64
            QByteArray privateData;
65
            BinaryStream privateStream(&privateData);
66
            bigIntToStream(rsaKey.get_n(), privateStream, 1);
67
            bigIntToStream(rsaKey.get_e(), privateStream);
68
            bigIntToStream(rsaKey.get_d(), privateStream, 1);
69
            bigIntToStream(rsaKey.get_c(), privateStream, 1);
70
            bigIntToStream(rsaKey.get_p(), privateStream, 1);
71
            bigIntToStream(rsaKey.get_q(), privateStream, 1);
72

73
            key.setType("ssh-rsa");
74
            key.setCheck(randomGen()->randomUInt(std::numeric_limits<quint32>::max() - 1) + 1);
75
            key.setPublicData(publicData);
76
            key.setPrivateData(privateData);
77
            key.setComment("id_rsa");
78
            return true;
79
        } catch (std::exception& e) {
80
            return false;
81
        }
82
    }
83

84
    bool generateECDSA(OpenSSHKey& key, int bits)
85
    {
86
        auto rng = randomGen()->getRng();
87
        QString group = QString("nistp%1").arg(bits);
88

89
        try {
90
            Botan::EC_Group domain(QString("secp%1r1").arg(bits).toStdString());
91
            Botan::ECDSA_PrivateKey ecdsaKey(*rng, domain);
92

93
            QByteArray publicData;
94
            BinaryStream publicStream(&publicData);
95
            publicStream.writeString(group);
96
            vectorToStream(ecdsaKey.public_key_bits(), publicStream);
97

98
            QByteArray privateData;
99
            BinaryStream privateStream(&privateData);
100
            privateStream.writeString(group);
101
            vectorToStream(ecdsaKey.public_key_bits(), privateStream);
102
            bigIntToStream(ecdsaKey.private_value(), privateStream, 1);
103

104
            key.setType("ecdsa-sha2-" + group);
105
            key.setCheck(randomGen()->randomUInt(std::numeric_limits<quint32>::max() - 1) + 1);
106
            key.setPublicData(publicData);
107
            key.setPrivateData(privateData);
108
            key.setComment("id_ecdsa");
109
            return true;
110
        } catch (std::exception& e) {
111
            return false;
112
        }
113
    }
114

115
    bool generateEd25519(OpenSSHKey& key)
116
    {
117
        auto rng = randomGen()->getRng();
118

119
        try {
120
            Botan::Ed25519_PrivateKey ed25519Key(*rng);
121

122
            QByteArray publicData;
123
            BinaryStream publicStream(&publicData);
124
            vectorToStream(ed25519Key.get_public_key(), publicStream);
125

126
            QByteArray privateData;
127
            BinaryStream privateStream(&privateData);
128
            vectorToStream(ed25519Key.get_public_key(), privateStream);
129
            vectorToStream(ed25519Key.get_private_key(), privateStream);
130

131
            key.setType("ssh-ed25519");
132
            key.setCheck(randomGen()->randomUInt(std::numeric_limits<quint32>::max() - 1) + 1);
133
            key.setPublicData(publicData);
134
            key.setPrivateData(privateData);
135
            key.setComment("id_ed25519");
136
            return true;
137
        } catch (std::exception& e) {
138
            return false;
139
        }
140
    }
141
} // namespace OpenSSHKeyGen
142

Использование cookies

Мы используем файлы cookie в соответствии с Политикой конфиденциальности и Политикой использования cookies.

Нажимая кнопку «Принимаю», Вы даете АО «СберТех» согласие на обработку Ваших персональных данных в целях совершенствования нашего веб-сайта и Сервиса GitVerse, а также повышения удобства их использования.

Запретить использование cookies Вы можете самостоятельно в настройках Вашего браузера.