Mercurial > dropbear
annotate keyimport.c @ 1659:d32bcb5c557d
Add Ed25519 support (#91)
* Add support for Ed25519 as a public key type
Ed25519 is a elliptic curve signature scheme that offers
better security than ECDSA and DSA and good performance. It may be
used for both user and host keys.
OpenSSH key import and fuzzer are not supported yet.
Initially inspired by Peter Szabo.
* Add curve25519 and ed25519 fuzzers
* Add import and export of Ed25519 keys
author | Vladislav Grishenko <themiron@users.noreply.github.com> |
---|---|
date | Wed, 11 Mar 2020 21:09:45 +0500 |
parents | 315fcba6960e |
children | ba6fc7afe1c5 |
rev | line source |
---|---|
4
fe6bca95afa7
Makefile.in contains updated files required
Matt Johnston <matt@ucc.asn.au>
parents:
diff
changeset
|
1 /* |
fe6bca95afa7
Makefile.in contains updated files required
Matt Johnston <matt@ucc.asn.au>
parents:
diff
changeset
|
2 * Based on PuTTY's import.c for importing/exporting OpenSSH and SSH.com |
fe6bca95afa7
Makefile.in contains updated files required
Matt Johnston <matt@ucc.asn.au>
parents:
diff
changeset
|
3 * keyfiles. |
fe6bca95afa7
Makefile.in contains updated files required
Matt Johnston <matt@ucc.asn.au>
parents:
diff
changeset
|
4 * |
fe6bca95afa7
Makefile.in contains updated files required
Matt Johnston <matt@ucc.asn.au>
parents:
diff
changeset
|
5 * Modifications copyright 2003 Matt Johnston |
fe6bca95afa7
Makefile.in contains updated files required
Matt Johnston <matt@ucc.asn.au>
parents:
diff
changeset
|
6 * |
fe6bca95afa7
Makefile.in contains updated files required
Matt Johnston <matt@ucc.asn.au>
parents:
diff
changeset
|
7 * PuTTY is copyright 1997-2003 Simon Tatham. |
fe6bca95afa7
Makefile.in contains updated files required
Matt Johnston <matt@ucc.asn.au>
parents:
diff
changeset
|
8 * |
fe6bca95afa7
Makefile.in contains updated files required
Matt Johnston <matt@ucc.asn.au>
parents:
diff
changeset
|
9 * Portions copyright Robert de Bath, Joris van Rantwijk, Delian |
fe6bca95afa7
Makefile.in contains updated files required
Matt Johnston <matt@ucc.asn.au>
parents:
diff
changeset
|
10 * Delchev, Andreas Schultz, Jeroen Massar, Wez Furlong, Nicolas Barry, |
fe6bca95afa7
Makefile.in contains updated files required
Matt Johnston <matt@ucc.asn.au>
parents:
diff
changeset
|
11 * Justin Bradford, and CORE SDI S.A. |
fe6bca95afa7
Makefile.in contains updated files required
Matt Johnston <matt@ucc.asn.au>
parents:
diff
changeset
|
12 * |
fe6bca95afa7
Makefile.in contains updated files required
Matt Johnston <matt@ucc.asn.au>
parents:
diff
changeset
|
13 * Permission is hereby granted, free of charge, to any person |
fe6bca95afa7
Makefile.in contains updated files required
Matt Johnston <matt@ucc.asn.au>
parents:
diff
changeset
|
14 * obtaining a copy of this software and associated documentation files |
fe6bca95afa7
Makefile.in contains updated files required
Matt Johnston <matt@ucc.asn.au>
parents:
diff
changeset
|
15 * (the "Software"), to deal in the Software without restriction, |
fe6bca95afa7
Makefile.in contains updated files required
Matt Johnston <matt@ucc.asn.au>
parents:
diff
changeset
|
16 * including without limitation the rights to use, copy, modify, merge, |
fe6bca95afa7
Makefile.in contains updated files required
Matt Johnston <matt@ucc.asn.au>
parents:
diff
changeset
|
17 * publish, distribute, sublicense, and/or sell copies of the Software, |
fe6bca95afa7
Makefile.in contains updated files required
Matt Johnston <matt@ucc.asn.au>
parents:
diff
changeset
|
18 * and to permit persons to whom the Software is furnished to do so, |
fe6bca95afa7
Makefile.in contains updated files required
Matt Johnston <matt@ucc.asn.au>
parents:
diff
changeset
|
19 * subject to the following conditions: |
fe6bca95afa7
Makefile.in contains updated files required
Matt Johnston <matt@ucc.asn.au>
parents:
diff
changeset
|
20 * |
fe6bca95afa7
Makefile.in contains updated files required
Matt Johnston <matt@ucc.asn.au>
parents:
diff
changeset
|
21 * The above copyright notice and this permission notice shall be |
fe6bca95afa7
Makefile.in contains updated files required
Matt Johnston <matt@ucc.asn.au>
parents:
diff
changeset
|
22 * included in all copies or substantial portions of the Software. |
fe6bca95afa7
Makefile.in contains updated files required
Matt Johnston <matt@ucc.asn.au>
parents:
diff
changeset
|
23 * |
fe6bca95afa7
Makefile.in contains updated files required
Matt Johnston <matt@ucc.asn.au>
parents:
diff
changeset
|
24 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, |
fe6bca95afa7
Makefile.in contains updated files required
Matt Johnston <matt@ucc.asn.au>
parents:
diff
changeset
|
25 * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF |
fe6bca95afa7
Makefile.in contains updated files required
Matt Johnston <matt@ucc.asn.au>
parents:
diff
changeset
|
26 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND |
fe6bca95afa7
Makefile.in contains updated files required
Matt Johnston <matt@ucc.asn.au>
parents:
diff
changeset
|
27 * NONINFRINGEMENT. IN NO EVENT SHALL THE COPYRIGHT HOLDERS BE LIABLE |
fe6bca95afa7
Makefile.in contains updated files required
Matt Johnston <matt@ucc.asn.au>
parents:
diff
changeset
|
28 * FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF |
fe6bca95afa7
Makefile.in contains updated files required
Matt Johnston <matt@ucc.asn.au>
parents:
diff
changeset
|
29 * CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION |
fe6bca95afa7
Makefile.in contains updated files required
Matt Johnston <matt@ucc.asn.au>
parents:
diff
changeset
|
30 * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. |
fe6bca95afa7
Makefile.in contains updated files required
Matt Johnston <matt@ucc.asn.au>
parents:
diff
changeset
|
31 */ |
fe6bca95afa7
Makefile.in contains updated files required
Matt Johnston <matt@ucc.asn.au>
parents:
diff
changeset
|
32 |
fe6bca95afa7
Makefile.in contains updated files required
Matt Johnston <matt@ucc.asn.au>
parents:
diff
changeset
|
33 #include "keyimport.h" |
fe6bca95afa7
Makefile.in contains updated files required
Matt Johnston <matt@ucc.asn.au>
parents:
diff
changeset
|
34 #include "bignum.h" |
fe6bca95afa7
Makefile.in contains updated files required
Matt Johnston <matt@ucc.asn.au>
parents:
diff
changeset
|
35 #include "buffer.h" |
fe6bca95afa7
Makefile.in contains updated files required
Matt Johnston <matt@ucc.asn.au>
parents:
diff
changeset
|
36 #include "dbutil.h" |
806
71e7d31f7671
hackish ECC import code from OpenSSH
Matt Johnston <matt@ucc.asn.au>
parents:
793
diff
changeset
|
37 #include "ecc.h" |
1659
d32bcb5c557d
Add Ed25519 support (#91)
Vladislav Grishenko <themiron@users.noreply.github.com>
parents:
1638
diff
changeset
|
38 #include "ssh.h" |
d32bcb5c557d
Add Ed25519 support (#91)
Vladislav Grishenko <themiron@users.noreply.github.com>
parents:
1638
diff
changeset
|
39 |
d32bcb5c557d
Add Ed25519 support (#91)
Vladislav Grishenko <themiron@users.noreply.github.com>
parents:
1638
diff
changeset
|
40 static const unsigned char OSSH_PKEY_BLOB[] = |
d32bcb5c557d
Add Ed25519 support (#91)
Vladislav Grishenko <themiron@users.noreply.github.com>
parents:
1638
diff
changeset
|
41 "openssh-key-v1\0" /* AUTH_MAGIC */ |
d32bcb5c557d
Add Ed25519 support (#91)
Vladislav Grishenko <themiron@users.noreply.github.com>
parents:
1638
diff
changeset
|
42 "\0\0\0\4none" /* cipher name*/ |
d32bcb5c557d
Add Ed25519 support (#91)
Vladislav Grishenko <themiron@users.noreply.github.com>
parents:
1638
diff
changeset
|
43 "\0\0\0\4none" /* kdf name */ |
d32bcb5c557d
Add Ed25519 support (#91)
Vladislav Grishenko <themiron@users.noreply.github.com>
parents:
1638
diff
changeset
|
44 "\0\0\0\0" /* kdf */ |
d32bcb5c557d
Add Ed25519 support (#91)
Vladislav Grishenko <themiron@users.noreply.github.com>
parents:
1638
diff
changeset
|
45 "\0\0\0\1"; /* key num */ |
d32bcb5c557d
Add Ed25519 support (#91)
Vladislav Grishenko <themiron@users.noreply.github.com>
parents:
1638
diff
changeset
|
46 #define OSSH_PKEY_BLOBLEN (sizeof(OSSH_PKEY_BLOB) - 1) |
806
71e7d31f7671
hackish ECC import code from OpenSSH
Matt Johnston <matt@ucc.asn.au>
parents:
793
diff
changeset
|
47 |
1295
750ec4ec4cbe
Convert #ifdef to #if, other build changes
Matt Johnston <matt@ucc.asn.au>
parents:
1294
diff
changeset
|
48 #if DROPBEAR_ECDSA |
836
d7d9f1612d51
writing out openssh ecc keys works
Matt Johnston <matt@ucc.asn.au>
parents:
807
diff
changeset
|
49 static const unsigned char OID_SEC256R1_BLOB[] = {0x2a, 0x86, 0x48, 0xce, 0x3d, 0x03, 0x01, 0x07}; |
d7d9f1612d51
writing out openssh ecc keys works
Matt Johnston <matt@ucc.asn.au>
parents:
807
diff
changeset
|
50 static const unsigned char OID_SEC384R1_BLOB[] = {0x2b, 0x81, 0x04, 0x00, 0x22}; |
d7d9f1612d51
writing out openssh ecc keys works
Matt Johnston <matt@ucc.asn.au>
parents:
807
diff
changeset
|
51 static const unsigned char OID_SEC521R1_BLOB[] = {0x2b, 0x81, 0x04, 0x00, 0x23}; |
1294
56aba7dedbea
options for disabling "normal" DH
Matt Johnston <matt@ucc.asn.au>
parents:
1250
diff
changeset
|
52 #endif |
4
fe6bca95afa7
Makefile.in contains updated files required
Matt Johnston <matt@ucc.asn.au>
parents:
diff
changeset
|
53 |
fe6bca95afa7
Makefile.in contains updated files required
Matt Johnston <matt@ucc.asn.au>
parents:
diff
changeset
|
54 #define PUT_32BIT(cp, value) do { \ |
fe6bca95afa7
Makefile.in contains updated files required
Matt Johnston <matt@ucc.asn.au>
parents:
diff
changeset
|
55 (cp)[3] = (unsigned char)(value); \ |
fe6bca95afa7
Makefile.in contains updated files required
Matt Johnston <matt@ucc.asn.au>
parents:
diff
changeset
|
56 (cp)[2] = (unsigned char)((value) >> 8); \ |
fe6bca95afa7
Makefile.in contains updated files required
Matt Johnston <matt@ucc.asn.au>
parents:
diff
changeset
|
57 (cp)[1] = (unsigned char)((value) >> 16); \ |
fe6bca95afa7
Makefile.in contains updated files required
Matt Johnston <matt@ucc.asn.au>
parents:
diff
changeset
|
58 (cp)[0] = (unsigned char)((value) >> 24); } while (0) |
fe6bca95afa7
Makefile.in contains updated files required
Matt Johnston <matt@ucc.asn.au>
parents:
diff
changeset
|
59 |
fe6bca95afa7
Makefile.in contains updated files required
Matt Johnston <matt@ucc.asn.au>
parents:
diff
changeset
|
60 #define GET_32BIT(cp) \ |
1308 | 61 (((unsigned long)(unsigned char)(cp)[0] << 24) | \ |
62 ((unsigned long)(unsigned char)(cp)[1] << 16) | \ | |
63 ((unsigned long)(unsigned char)(cp)[2] << 8) | \ | |
64 ((unsigned long)(unsigned char)(cp)[3])) | |
4
fe6bca95afa7
Makefile.in contains updated files required
Matt Johnston <matt@ucc.asn.au>
parents:
diff
changeset
|
65 |
fe6bca95afa7
Makefile.in contains updated files required
Matt Johnston <matt@ucc.asn.au>
parents:
diff
changeset
|
66 static int openssh_encrypted(const char *filename); |
1459
06d52bcb8094
Pointer parameter could be declared as pointing to const
Francois Perrad <francois.perrad@gadz.org>
parents:
1395
diff
changeset
|
67 static sign_key *openssh_read(const char *filename, const char *passphrase); |
4
fe6bca95afa7
Makefile.in contains updated files required
Matt Johnston <matt@ucc.asn.au>
parents:
diff
changeset
|
68 static int openssh_write(const char *filename, sign_key *key, |
1459
06d52bcb8094
Pointer parameter could be declared as pointing to const
Francois Perrad <francois.perrad@gadz.org>
parents:
1395
diff
changeset
|
69 const char *passphrase); |
4
fe6bca95afa7
Makefile.in contains updated files required
Matt Johnston <matt@ucc.asn.au>
parents:
diff
changeset
|
70 |
fe6bca95afa7
Makefile.in contains updated files required
Matt Johnston <matt@ucc.asn.au>
parents:
diff
changeset
|
71 static int dropbear_write(const char*filename, sign_key * key); |
fe6bca95afa7
Makefile.in contains updated files required
Matt Johnston <matt@ucc.asn.au>
parents:
diff
changeset
|
72 static sign_key *dropbear_read(const char* filename); |
fe6bca95afa7
Makefile.in contains updated files required
Matt Johnston <matt@ucc.asn.au>
parents:
diff
changeset
|
73 |
1306
34e6127ef02e
merge fixes from PuTTY import.c
Matt Johnston <matt@ucc.asn.au>
parents:
1250
diff
changeset
|
74 static int toint(unsigned u); |
34e6127ef02e
merge fixes from PuTTY import.c
Matt Johnston <matt@ucc.asn.au>
parents:
1250
diff
changeset
|
75 |
4
fe6bca95afa7
Makefile.in contains updated files required
Matt Johnston <matt@ucc.asn.au>
parents:
diff
changeset
|
76 #if 0 |
fe6bca95afa7
Makefile.in contains updated files required
Matt Johnston <matt@ucc.asn.au>
parents:
diff
changeset
|
77 static int sshcom_encrypted(const char *filename, char **comment); |
fe6bca95afa7
Makefile.in contains updated files required
Matt Johnston <matt@ucc.asn.au>
parents:
diff
changeset
|
78 static struct ssh2_userkey *sshcom_read(const char *filename, char *passphrase); |
fe6bca95afa7
Makefile.in contains updated files required
Matt Johnston <matt@ucc.asn.au>
parents:
diff
changeset
|
79 static int sshcom_write(const char *filename, struct ssh2_userkey *key, |
1308 | 80 char *passphrase); |
4
fe6bca95afa7
Makefile.in contains updated files required
Matt Johnston <matt@ucc.asn.au>
parents:
diff
changeset
|
81 #endif |
fe6bca95afa7
Makefile.in contains updated files required
Matt Johnston <matt@ucc.asn.au>
parents:
diff
changeset
|
82 |
fe6bca95afa7
Makefile.in contains updated files required
Matt Johnston <matt@ucc.asn.au>
parents:
diff
changeset
|
83 int import_encrypted(const char* filename, int filetype) { |
fe6bca95afa7
Makefile.in contains updated files required
Matt Johnston <matt@ucc.asn.au>
parents:
diff
changeset
|
84 |
fe6bca95afa7
Makefile.in contains updated files required
Matt Johnston <matt@ucc.asn.au>
parents:
diff
changeset
|
85 if (filetype == KEYFILE_OPENSSH) { |
fe6bca95afa7
Makefile.in contains updated files required
Matt Johnston <matt@ucc.asn.au>
parents:
diff
changeset
|
86 return openssh_encrypted(filename); |
fe6bca95afa7
Makefile.in contains updated files required
Matt Johnston <matt@ucc.asn.au>
parents:
diff
changeset
|
87 #if 0 |
fe6bca95afa7
Makefile.in contains updated files required
Matt Johnston <matt@ucc.asn.au>
parents:
diff
changeset
|
88 } else if (filetype == KEYFILE_SSHCOM) { |
fe6bca95afa7
Makefile.in contains updated files required
Matt Johnston <matt@ucc.asn.au>
parents:
diff
changeset
|
89 return sshcom_encrypted(filename, NULL); |
fe6bca95afa7
Makefile.in contains updated files required
Matt Johnston <matt@ucc.asn.au>
parents:
diff
changeset
|
90 #endif |
1308 | 91 } |
92 return 0; | |
4
fe6bca95afa7
Makefile.in contains updated files required
Matt Johnston <matt@ucc.asn.au>
parents:
diff
changeset
|
93 } |
fe6bca95afa7
Makefile.in contains updated files required
Matt Johnston <matt@ucc.asn.au>
parents:
diff
changeset
|
94 |
1459
06d52bcb8094
Pointer parameter could be declared as pointing to const
Francois Perrad <francois.perrad@gadz.org>
parents:
1395
diff
changeset
|
95 sign_key *import_read(const char *filename, const char *passphrase, int filetype) { |
4
fe6bca95afa7
Makefile.in contains updated files required
Matt Johnston <matt@ucc.asn.au>
parents:
diff
changeset
|
96 |
fe6bca95afa7
Makefile.in contains updated files required
Matt Johnston <matt@ucc.asn.au>
parents:
diff
changeset
|
97 if (filetype == KEYFILE_OPENSSH) { |
fe6bca95afa7
Makefile.in contains updated files required
Matt Johnston <matt@ucc.asn.au>
parents:
diff
changeset
|
98 return openssh_read(filename, passphrase); |
fe6bca95afa7
Makefile.in contains updated files required
Matt Johnston <matt@ucc.asn.au>
parents:
diff
changeset
|
99 } else if (filetype == KEYFILE_DROPBEAR) { |
fe6bca95afa7
Makefile.in contains updated files required
Matt Johnston <matt@ucc.asn.au>
parents:
diff
changeset
|
100 return dropbear_read(filename); |
fe6bca95afa7
Makefile.in contains updated files required
Matt Johnston <matt@ucc.asn.au>
parents:
diff
changeset
|
101 #if 0 |
fe6bca95afa7
Makefile.in contains updated files required
Matt Johnston <matt@ucc.asn.au>
parents:
diff
changeset
|
102 } else if (filetype == KEYFILE_SSHCOM) { |
fe6bca95afa7
Makefile.in contains updated files required
Matt Johnston <matt@ucc.asn.au>
parents:
diff
changeset
|
103 return sshcom_read(filename, passphrase); |
fe6bca95afa7
Makefile.in contains updated files required
Matt Johnston <matt@ucc.asn.au>
parents:
diff
changeset
|
104 #endif |
fe6bca95afa7
Makefile.in contains updated files required
Matt Johnston <matt@ucc.asn.au>
parents:
diff
changeset
|
105 } |
1308 | 106 return NULL; |
4
fe6bca95afa7
Makefile.in contains updated files required
Matt Johnston <matt@ucc.asn.au>
parents:
diff
changeset
|
107 } |
fe6bca95afa7
Makefile.in contains updated files required
Matt Johnston <matt@ucc.asn.au>
parents:
diff
changeset
|
108 |
1459
06d52bcb8094
Pointer parameter could be declared as pointing to const
Francois Perrad <francois.perrad@gadz.org>
parents:
1395
diff
changeset
|
109 int import_write(const char *filename, sign_key *key, const char *passphrase, |
4
fe6bca95afa7
Makefile.in contains updated files required
Matt Johnston <matt@ucc.asn.au>
parents:
diff
changeset
|
110 int filetype) { |
fe6bca95afa7
Makefile.in contains updated files required
Matt Johnston <matt@ucc.asn.au>
parents:
diff
changeset
|
111 |
fe6bca95afa7
Makefile.in contains updated files required
Matt Johnston <matt@ucc.asn.au>
parents:
diff
changeset
|
112 if (filetype == KEYFILE_OPENSSH) { |
fe6bca95afa7
Makefile.in contains updated files required
Matt Johnston <matt@ucc.asn.au>
parents:
diff
changeset
|
113 return openssh_write(filename, key, passphrase); |
fe6bca95afa7
Makefile.in contains updated files required
Matt Johnston <matt@ucc.asn.au>
parents:
diff
changeset
|
114 } else if (filetype == KEYFILE_DROPBEAR) { |
fe6bca95afa7
Makefile.in contains updated files required
Matt Johnston <matt@ucc.asn.au>
parents:
diff
changeset
|
115 return dropbear_write(filename, key); |
fe6bca95afa7
Makefile.in contains updated files required
Matt Johnston <matt@ucc.asn.au>
parents:
diff
changeset
|
116 #if 0 |
fe6bca95afa7
Makefile.in contains updated files required
Matt Johnston <matt@ucc.asn.au>
parents:
diff
changeset
|
117 } else if (filetype == KEYFILE_SSHCOM) { |
fe6bca95afa7
Makefile.in contains updated files required
Matt Johnston <matt@ucc.asn.au>
parents:
diff
changeset
|
118 return sshcom_write(filename, key, passphrase); |
fe6bca95afa7
Makefile.in contains updated files required
Matt Johnston <matt@ucc.asn.au>
parents:
diff
changeset
|
119 #endif |
fe6bca95afa7
Makefile.in contains updated files required
Matt Johnston <matt@ucc.asn.au>
parents:
diff
changeset
|
120 } |
1308 | 121 return 0; |
4
fe6bca95afa7
Makefile.in contains updated files required
Matt Johnston <matt@ucc.asn.au>
parents:
diff
changeset
|
122 } |
fe6bca95afa7
Makefile.in contains updated files required
Matt Johnston <matt@ucc.asn.au>
parents:
diff
changeset
|
123 |
fe6bca95afa7
Makefile.in contains updated files required
Matt Johnston <matt@ucc.asn.au>
parents:
diff
changeset
|
124 static sign_key *dropbear_read(const char* filename) { |
fe6bca95afa7
Makefile.in contains updated files required
Matt Johnston <matt@ucc.asn.au>
parents:
diff
changeset
|
125 |
fe6bca95afa7
Makefile.in contains updated files required
Matt Johnston <matt@ucc.asn.au>
parents:
diff
changeset
|
126 buffer * buf = NULL; |
fe6bca95afa7
Makefile.in contains updated files required
Matt Johnston <matt@ucc.asn.au>
parents:
diff
changeset
|
127 sign_key *ret = NULL; |
846
b298bb438625
refactor key generation, make it generate as required.
Matt Johnston <matt@ucc.asn.au>
parents:
845
diff
changeset
|
128 enum signkey_type type; |
4
fe6bca95afa7
Makefile.in contains updated files required
Matt Johnston <matt@ucc.asn.au>
parents:
diff
changeset
|
129 |
73
0bf5cebe622c
Dropbearkey can now print out pubkey portions
Matt Johnston <matt@ucc.asn.au>
parents:
4
diff
changeset
|
130 buf = buf_new(MAX_PRIVKEY_SIZE); |
0bf5cebe622c
Dropbearkey can now print out pubkey portions
Matt Johnston <matt@ucc.asn.au>
parents:
4
diff
changeset
|
131 if (buf_readfile(buf, filename) == DROPBEAR_FAILURE) { |
4
fe6bca95afa7
Makefile.in contains updated files required
Matt Johnston <matt@ucc.asn.au>
parents:
diff
changeset
|
132 goto error; |
fe6bca95afa7
Makefile.in contains updated files required
Matt Johnston <matt@ucc.asn.au>
parents:
diff
changeset
|
133 } |
fe6bca95afa7
Makefile.in contains updated files required
Matt Johnston <matt@ucc.asn.au>
parents:
diff
changeset
|
134 |
fe6bca95afa7
Makefile.in contains updated files required
Matt Johnston <matt@ucc.asn.au>
parents:
diff
changeset
|
135 buf_setpos(buf, 0); |
fe6bca95afa7
Makefile.in contains updated files required
Matt Johnston <matt@ucc.asn.au>
parents:
diff
changeset
|
136 ret = new_sign_key(); |
fe6bca95afa7
Makefile.in contains updated files required
Matt Johnston <matt@ucc.asn.au>
parents:
diff
changeset
|
137 |
fe6bca95afa7
Makefile.in contains updated files required
Matt Johnston <matt@ucc.asn.au>
parents:
diff
changeset
|
138 type = DROPBEAR_SIGNKEY_ANY; |
fe6bca95afa7
Makefile.in contains updated files required
Matt Johnston <matt@ucc.asn.au>
parents:
diff
changeset
|
139 if (buf_get_priv_key(buf, ret, &type) == DROPBEAR_FAILURE){ |
fe6bca95afa7
Makefile.in contains updated files required
Matt Johnston <matt@ucc.asn.au>
parents:
diff
changeset
|
140 goto error; |
fe6bca95afa7
Makefile.in contains updated files required
Matt Johnston <matt@ucc.asn.au>
parents:
diff
changeset
|
141 } |
fe6bca95afa7
Makefile.in contains updated files required
Matt Johnston <matt@ucc.asn.au>
parents:
diff
changeset
|
142 buf_free(buf); |
fe6bca95afa7
Makefile.in contains updated files required
Matt Johnston <matt@ucc.asn.au>
parents:
diff
changeset
|
143 |
836
d7d9f1612d51
writing out openssh ecc keys works
Matt Johnston <matt@ucc.asn.au>
parents:
807
diff
changeset
|
144 ret->type = type; |
d7d9f1612d51
writing out openssh ecc keys works
Matt Johnston <matt@ucc.asn.au>
parents:
807
diff
changeset
|
145 |
4
fe6bca95afa7
Makefile.in contains updated files required
Matt Johnston <matt@ucc.asn.au>
parents:
diff
changeset
|
146 return ret; |
fe6bca95afa7
Makefile.in contains updated files required
Matt Johnston <matt@ucc.asn.au>
parents:
diff
changeset
|
147 |
fe6bca95afa7
Makefile.in contains updated files required
Matt Johnston <matt@ucc.asn.au>
parents:
diff
changeset
|
148 error: |
fe6bca95afa7
Makefile.in contains updated files required
Matt Johnston <matt@ucc.asn.au>
parents:
diff
changeset
|
149 if (buf) { |
fe6bca95afa7
Makefile.in contains updated files required
Matt Johnston <matt@ucc.asn.au>
parents:
diff
changeset
|
150 buf_free(buf); |
fe6bca95afa7
Makefile.in contains updated files required
Matt Johnston <matt@ucc.asn.au>
parents:
diff
changeset
|
151 } |
fe6bca95afa7
Makefile.in contains updated files required
Matt Johnston <matt@ucc.asn.au>
parents:
diff
changeset
|
152 if (ret) { |
fe6bca95afa7
Makefile.in contains updated files required
Matt Johnston <matt@ucc.asn.au>
parents:
diff
changeset
|
153 sign_key_free(ret); |
fe6bca95afa7
Makefile.in contains updated files required
Matt Johnston <matt@ucc.asn.au>
parents:
diff
changeset
|
154 } |
fe6bca95afa7
Makefile.in contains updated files required
Matt Johnston <matt@ucc.asn.au>
parents:
diff
changeset
|
155 return NULL; |
fe6bca95afa7
Makefile.in contains updated files required
Matt Johnston <matt@ucc.asn.au>
parents:
diff
changeset
|
156 } |
fe6bca95afa7
Makefile.in contains updated files required
Matt Johnston <matt@ucc.asn.au>
parents:
diff
changeset
|
157 |
fe6bca95afa7
Makefile.in contains updated files required
Matt Johnston <matt@ucc.asn.au>
parents:
diff
changeset
|
158 /* returns 0 on fail, 1 on success */ |
fe6bca95afa7
Makefile.in contains updated files required
Matt Johnston <matt@ucc.asn.au>
parents:
diff
changeset
|
159 static int dropbear_write(const char*filename, sign_key * key) { |
fe6bca95afa7
Makefile.in contains updated files required
Matt Johnston <matt@ucc.asn.au>
parents:
diff
changeset
|
160 |
fe6bca95afa7
Makefile.in contains updated files required
Matt Johnston <matt@ucc.asn.au>
parents:
diff
changeset
|
161 buffer * buf; |
fe6bca95afa7
Makefile.in contains updated files required
Matt Johnston <matt@ucc.asn.au>
parents:
diff
changeset
|
162 FILE*fp; |
fe6bca95afa7
Makefile.in contains updated files required
Matt Johnston <matt@ucc.asn.au>
parents:
diff
changeset
|
163 int len; |
fe6bca95afa7
Makefile.in contains updated files required
Matt Johnston <matt@ucc.asn.au>
parents:
diff
changeset
|
164 int ret; |
fe6bca95afa7
Makefile.in contains updated files required
Matt Johnston <matt@ucc.asn.au>
parents:
diff
changeset
|
165 |
73
0bf5cebe622c
Dropbearkey can now print out pubkey portions
Matt Johnston <matt@ucc.asn.au>
parents:
4
diff
changeset
|
166 buf = buf_new(MAX_PRIVKEY_SIZE); |
806
71e7d31f7671
hackish ECC import code from OpenSSH
Matt Johnston <matt@ucc.asn.au>
parents:
793
diff
changeset
|
167 buf_put_priv_key(buf, key, key->type); |
4
fe6bca95afa7
Makefile.in contains updated files required
Matt Johnston <matt@ucc.asn.au>
parents:
diff
changeset
|
168 |
87
680a0bc9df0a
Some small fixes for unused vars, and old messages
Matt Johnston <matt@ucc.asn.au>
parents:
73
diff
changeset
|
169 fp = fopen(filename, "w"); |
4
fe6bca95afa7
Makefile.in contains updated files required
Matt Johnston <matt@ucc.asn.au>
parents:
diff
changeset
|
170 if (!fp) { |
fe6bca95afa7
Makefile.in contains updated files required
Matt Johnston <matt@ucc.asn.au>
parents:
diff
changeset
|
171 ret = 0; |
fe6bca95afa7
Makefile.in contains updated files required
Matt Johnston <matt@ucc.asn.au>
parents:
diff
changeset
|
172 goto out; |
fe6bca95afa7
Makefile.in contains updated files required
Matt Johnston <matt@ucc.asn.au>
parents:
diff
changeset
|
173 } |
fe6bca95afa7
Makefile.in contains updated files required
Matt Johnston <matt@ucc.asn.au>
parents:
diff
changeset
|
174 |
fe6bca95afa7
Makefile.in contains updated files required
Matt Johnston <matt@ucc.asn.au>
parents:
diff
changeset
|
175 buf_setpos(buf, 0); |
fe6bca95afa7
Makefile.in contains updated files required
Matt Johnston <matt@ucc.asn.au>
parents:
diff
changeset
|
176 do { |
fe6bca95afa7
Makefile.in contains updated files required
Matt Johnston <matt@ucc.asn.au>
parents:
diff
changeset
|
177 len = fwrite(buf_getptr(buf, buf->len - buf->pos), |
fe6bca95afa7
Makefile.in contains updated files required
Matt Johnston <matt@ucc.asn.au>
parents:
diff
changeset
|
178 1, buf->len - buf->pos, fp); |
fe6bca95afa7
Makefile.in contains updated files required
Matt Johnston <matt@ucc.asn.au>
parents:
diff
changeset
|
179 buf_incrpos(buf, len); |
fe6bca95afa7
Makefile.in contains updated files required
Matt Johnston <matt@ucc.asn.au>
parents:
diff
changeset
|
180 } while (len > 0 && buf->len != buf->pos); |
fe6bca95afa7
Makefile.in contains updated files required
Matt Johnston <matt@ucc.asn.au>
parents:
diff
changeset
|
181 |
256
ac890087b8c1
* keyimport.c: fclose() the key file to make sure data gets written
Matt Johnston <matt@ucc.asn.au>
parents:
241
diff
changeset
|
182 fclose(fp); |
ac890087b8c1
* keyimport.c: fclose() the key file to make sure data gets written
Matt Johnston <matt@ucc.asn.au>
parents:
241
diff
changeset
|
183 |
4
fe6bca95afa7
Makefile.in contains updated files required
Matt Johnston <matt@ucc.asn.au>
parents:
diff
changeset
|
184 if (buf->pos != buf->len) { |
fe6bca95afa7
Makefile.in contains updated files required
Matt Johnston <matt@ucc.asn.au>
parents:
diff
changeset
|
185 ret = 0; |
fe6bca95afa7
Makefile.in contains updated files required
Matt Johnston <matt@ucc.asn.au>
parents:
diff
changeset
|
186 } else { |
fe6bca95afa7
Makefile.in contains updated files required
Matt Johnston <matt@ucc.asn.au>
parents:
diff
changeset
|
187 ret = 1; |
fe6bca95afa7
Makefile.in contains updated files required
Matt Johnston <matt@ucc.asn.au>
parents:
diff
changeset
|
188 } |
fe6bca95afa7
Makefile.in contains updated files required
Matt Johnston <matt@ucc.asn.au>
parents:
diff
changeset
|
189 out: |
fe6bca95afa7
Makefile.in contains updated files required
Matt Johnston <matt@ucc.asn.au>
parents:
diff
changeset
|
190 buf_free(buf); |
fe6bca95afa7
Makefile.in contains updated files required
Matt Johnston <matt@ucc.asn.au>
parents:
diff
changeset
|
191 return ret; |
fe6bca95afa7
Makefile.in contains updated files required
Matt Johnston <matt@ucc.asn.au>
parents:
diff
changeset
|
192 } |
fe6bca95afa7
Makefile.in contains updated files required
Matt Johnston <matt@ucc.asn.au>
parents:
diff
changeset
|
193 |
fe6bca95afa7
Makefile.in contains updated files required
Matt Johnston <matt@ucc.asn.au>
parents:
diff
changeset
|
194 |
fe6bca95afa7
Makefile.in contains updated files required
Matt Johnston <matt@ucc.asn.au>
parents:
diff
changeset
|
195 /* ---------------------------------------------------------------------- |
fe6bca95afa7
Makefile.in contains updated files required
Matt Johnston <matt@ucc.asn.au>
parents:
diff
changeset
|
196 * Helper routines. (The base64 ones are defined in sshpubk.c.) |
fe6bca95afa7
Makefile.in contains updated files required
Matt Johnston <matt@ucc.asn.au>
parents:
diff
changeset
|
197 */ |
fe6bca95afa7
Makefile.in contains updated files required
Matt Johnston <matt@ucc.asn.au>
parents:
diff
changeset
|
198 |
fe6bca95afa7
Makefile.in contains updated files required
Matt Johnston <matt@ucc.asn.au>
parents:
diff
changeset
|
199 #define isbase64(c) ( ((c) >= 'A' && (c) <= 'Z') || \ |
1308 | 200 ((c) >= 'a' && (c) <= 'z') || \ |
201 ((c) >= '0' && (c) <= '9') || \ | |
202 (c) == '+' || (c) == '/' || (c) == '=' \ | |
203 ) | |
4
fe6bca95afa7
Makefile.in contains updated files required
Matt Johnston <matt@ucc.asn.au>
parents:
diff
changeset
|
204 |
fe6bca95afa7
Makefile.in contains updated files required
Matt Johnston <matt@ucc.asn.au>
parents:
diff
changeset
|
205 /* cpl has to be less than 100 */ |
1459
06d52bcb8094
Pointer parameter could be declared as pointing to const
Francois Perrad <francois.perrad@gadz.org>
parents:
1395
diff
changeset
|
206 static void base64_encode_fp(FILE * fp, const unsigned char *data, |
4
fe6bca95afa7
Makefile.in contains updated files required
Matt Johnston <matt@ucc.asn.au>
parents:
diff
changeset
|
207 int datalen, int cpl) |
fe6bca95afa7
Makefile.in contains updated files required
Matt Johnston <matt@ucc.asn.au>
parents:
diff
changeset
|
208 { |
1094
c45d65392c1a
Fix pointer differ in signess warnings [-Werror=pointer-sign]
Gaël PORTAY <gael.portay@gmail.com>
parents:
1089
diff
changeset
|
209 unsigned char out[100]; |
1250 | 210 int n; |
4
fe6bca95afa7
Makefile.in contains updated files required
Matt Johnston <matt@ucc.asn.au>
parents:
diff
changeset
|
211 unsigned long outlen; |
fe6bca95afa7
Makefile.in contains updated files required
Matt Johnston <matt@ucc.asn.au>
parents:
diff
changeset
|
212 int rawcpl; |
fe6bca95afa7
Makefile.in contains updated files required
Matt Johnston <matt@ucc.asn.au>
parents:
diff
changeset
|
213 rawcpl = cpl * 3 / 4; |
241
c5d3ef11155f
* use own assertions which should get logged properly
Matt Johnston <matt@ucc.asn.au>
parents:
87
diff
changeset
|
214 dropbear_assert((unsigned int)cpl < sizeof(out)); |
4
fe6bca95afa7
Makefile.in contains updated files required
Matt Johnston <matt@ucc.asn.au>
parents:
diff
changeset
|
215 |
1250 | 216 while (datalen > 0) { |
4
fe6bca95afa7
Makefile.in contains updated files required
Matt Johnston <matt@ucc.asn.au>
parents:
diff
changeset
|
217 n = (datalen < rawcpl ? datalen : rawcpl); |
fe6bca95afa7
Makefile.in contains updated files required
Matt Johnston <matt@ucc.asn.au>
parents:
diff
changeset
|
218 outlen = sizeof(out); |
fe6bca95afa7
Makefile.in contains updated files required
Matt Johnston <matt@ucc.asn.au>
parents:
diff
changeset
|
219 base64_encode(data, n, out, &outlen); |
fe6bca95afa7
Makefile.in contains updated files required
Matt Johnston <matt@ucc.asn.au>
parents:
diff
changeset
|
220 data += n; |
fe6bca95afa7
Makefile.in contains updated files required
Matt Johnston <matt@ucc.asn.au>
parents:
diff
changeset
|
221 datalen -= n; |
fe6bca95afa7
Makefile.in contains updated files required
Matt Johnston <matt@ucc.asn.au>
parents:
diff
changeset
|
222 fwrite(out, 1, outlen, fp); |
fe6bca95afa7
Makefile.in contains updated files required
Matt Johnston <matt@ucc.asn.au>
parents:
diff
changeset
|
223 fputc('\n', fp); |
1250 | 224 } |
4
fe6bca95afa7
Makefile.in contains updated files required
Matt Johnston <matt@ucc.asn.au>
parents:
diff
changeset
|
225 } |
fe6bca95afa7
Makefile.in contains updated files required
Matt Johnston <matt@ucc.asn.au>
parents:
diff
changeset
|
226 /* |
fe6bca95afa7
Makefile.in contains updated files required
Matt Johnston <matt@ucc.asn.au>
parents:
diff
changeset
|
227 * Read an ASN.1/BER identifier and length pair. |
fe6bca95afa7
Makefile.in contains updated files required
Matt Johnston <matt@ucc.asn.au>
parents:
diff
changeset
|
228 * |
fe6bca95afa7
Makefile.in contains updated files required
Matt Johnston <matt@ucc.asn.au>
parents:
diff
changeset
|
229 * Flags are a combination of the #defines listed below. |
fe6bca95afa7
Makefile.in contains updated files required
Matt Johnston <matt@ucc.asn.au>
parents:
diff
changeset
|
230 * |
fe6bca95afa7
Makefile.in contains updated files required
Matt Johnston <matt@ucc.asn.au>
parents:
diff
changeset
|
231 * Returns -1 if unsuccessful; otherwise returns the number of |
fe6bca95afa7
Makefile.in contains updated files required
Matt Johnston <matt@ucc.asn.au>
parents:
diff
changeset
|
232 * bytes used out of the source data. |
fe6bca95afa7
Makefile.in contains updated files required
Matt Johnston <matt@ucc.asn.au>
parents:
diff
changeset
|
233 */ |
fe6bca95afa7
Makefile.in contains updated files required
Matt Johnston <matt@ucc.asn.au>
parents:
diff
changeset
|
234 |
fe6bca95afa7
Makefile.in contains updated files required
Matt Johnston <matt@ucc.asn.au>
parents:
diff
changeset
|
235 /* ASN.1 tag classes. */ |
fe6bca95afa7
Makefile.in contains updated files required
Matt Johnston <matt@ucc.asn.au>
parents:
diff
changeset
|
236 #define ASN1_CLASS_UNIVERSAL (0 << 6) |
fe6bca95afa7
Makefile.in contains updated files required
Matt Johnston <matt@ucc.asn.au>
parents:
diff
changeset
|
237 #define ASN1_CLASS_APPLICATION (1 << 6) |
fe6bca95afa7
Makefile.in contains updated files required
Matt Johnston <matt@ucc.asn.au>
parents:
diff
changeset
|
238 #define ASN1_CLASS_CONTEXT_SPECIFIC (2 << 6) |
fe6bca95afa7
Makefile.in contains updated files required
Matt Johnston <matt@ucc.asn.au>
parents:
diff
changeset
|
239 #define ASN1_CLASS_PRIVATE (3 << 6) |
fe6bca95afa7
Makefile.in contains updated files required
Matt Johnston <matt@ucc.asn.au>
parents:
diff
changeset
|
240 #define ASN1_CLASS_MASK (3 << 6) |
fe6bca95afa7
Makefile.in contains updated files required
Matt Johnston <matt@ucc.asn.au>
parents:
diff
changeset
|
241 |
fe6bca95afa7
Makefile.in contains updated files required
Matt Johnston <matt@ucc.asn.au>
parents:
diff
changeset
|
242 /* Primitive versus constructed bit. */ |
fe6bca95afa7
Makefile.in contains updated files required
Matt Johnston <matt@ucc.asn.au>
parents:
diff
changeset
|
243 #define ASN1_CONSTRUCTED (1 << 5) |
fe6bca95afa7
Makefile.in contains updated files required
Matt Johnston <matt@ucc.asn.au>
parents:
diff
changeset
|
244 |
fe6bca95afa7
Makefile.in contains updated files required
Matt Johnston <matt@ucc.asn.au>
parents:
diff
changeset
|
245 static int ber_read_id_len(void *source, int sourcelen, |
1308 | 246 int *id, int *length, int *flags) |
4
fe6bca95afa7
Makefile.in contains updated files required
Matt Johnston <matt@ucc.asn.au>
parents:
diff
changeset
|
247 { |
1308 | 248 unsigned char *p = (unsigned char *) source; |
4
fe6bca95afa7
Makefile.in contains updated files required
Matt Johnston <matt@ucc.asn.au>
parents:
diff
changeset
|
249 |
1308 | 250 if (sourcelen == 0) |
251 return -1; | |
4
fe6bca95afa7
Makefile.in contains updated files required
Matt Johnston <matt@ucc.asn.au>
parents:
diff
changeset
|
252 |
1308 | 253 *flags = (*p & 0xE0); |
254 if ((*p & 0x1F) == 0x1F) { | |
255 *id = 0; | |
256 while (*p & 0x80) { | |
257 p++, sourcelen--; | |
258 if (sourcelen == 0) | |
259 return -1; | |
260 *id = (*id << 7) | (*p & 0x7F); | |
261 } | |
262 p++, sourcelen--; | |
263 } else { | |
264 *id = *p & 0x1F; | |
265 p++, sourcelen--; | |
4
fe6bca95afa7
Makefile.in contains updated files required
Matt Johnston <matt@ucc.asn.au>
parents:
diff
changeset
|
266 } |
1306
34e6127ef02e
merge fixes from PuTTY import.c
Matt Johnston <matt@ucc.asn.au>
parents:
1250
diff
changeset
|
267 |
1308 | 268 if (sourcelen == 0) |
269 return -1; | |
4
fe6bca95afa7
Makefile.in contains updated files required
Matt Johnston <matt@ucc.asn.au>
parents:
diff
changeset
|
270 |
1308 | 271 if (*p & 0x80) { |
272 unsigned len; | |
273 int n = *p & 0x7F; | |
274 p++, sourcelen--; | |
275 if (sourcelen < n) | |
276 return -1; | |
277 len = 0; | |
278 while (n--) | |
279 len = (len << 8) | (*p++); | |
280 sourcelen -= n; | |
281 *length = toint(len); | |
282 } else { | |
283 *length = *p; | |
284 p++, sourcelen--; | |
285 } | |
4
fe6bca95afa7
Makefile.in contains updated files required
Matt Johnston <matt@ucc.asn.au>
parents:
diff
changeset
|
286 |
1308 | 287 if (*length < 0) { |
288 printf("Negative ASN.1 length\n"); | |
289 return -1; | |
290 } | |
1307
ad9c40aca3bc
add length checks for ecc too
Matt Johnston <matt@ucc.asn.au>
parents:
1306
diff
changeset
|
291 |
1308 | 292 return p - (unsigned char *) source; |
4
fe6bca95afa7
Makefile.in contains updated files required
Matt Johnston <matt@ucc.asn.au>
parents:
diff
changeset
|
293 } |
fe6bca95afa7
Makefile.in contains updated files required
Matt Johnston <matt@ucc.asn.au>
parents:
diff
changeset
|
294 |
fe6bca95afa7
Makefile.in contains updated files required
Matt Johnston <matt@ucc.asn.au>
parents:
diff
changeset
|
295 /* |
fe6bca95afa7
Makefile.in contains updated files required
Matt Johnston <matt@ucc.asn.au>
parents:
diff
changeset
|
296 * Write an ASN.1/BER identifier and length pair. Returns the |
fe6bca95afa7
Makefile.in contains updated files required
Matt Johnston <matt@ucc.asn.au>
parents:
diff
changeset
|
297 * number of bytes consumed. Assumes dest contains enough space. |
fe6bca95afa7
Makefile.in contains updated files required
Matt Johnston <matt@ucc.asn.au>
parents:
diff
changeset
|
298 * Will avoid writing anything if dest is NULL, but still return |
fe6bca95afa7
Makefile.in contains updated files required
Matt Johnston <matt@ucc.asn.au>
parents:
diff
changeset
|
299 * amount of space required. |
fe6bca95afa7
Makefile.in contains updated files required
Matt Johnston <matt@ucc.asn.au>
parents:
diff
changeset
|
300 */ |
fe6bca95afa7
Makefile.in contains updated files required
Matt Johnston <matt@ucc.asn.au>
parents:
diff
changeset
|
301 static int ber_write_id_len(void *dest, int id, int length, int flags) |
fe6bca95afa7
Makefile.in contains updated files required
Matt Johnston <matt@ucc.asn.au>
parents:
diff
changeset
|
302 { |
1308 | 303 unsigned char *d = (unsigned char *)dest; |
304 int len = 0; | |
4
fe6bca95afa7
Makefile.in contains updated files required
Matt Johnston <matt@ucc.asn.au>
parents:
diff
changeset
|
305 |
1308 | 306 if (id <= 30) { |
307 /* | |
308 * Identifier is one byte. | |
309 */ | |
310 len++; | |
311 if (d) *d++ = id | flags; | |
312 } else { | |
313 int n; | |
314 /* | |
315 * Identifier is multiple bytes: the first byte is 11111 | |
316 * plus the flags, and subsequent bytes encode the value of | |
317 * the identifier, 7 bits at a time, with the top bit of | |
318 * each byte 1 except the last one which is 0. | |
319 */ | |
320 len++; | |
321 if (d) *d++ = 0x1F | flags; | |
322 for (n = 1; (id >> (7*n)) > 0; n++) | |
4
fe6bca95afa7
Makefile.in contains updated files required
Matt Johnston <matt@ucc.asn.au>
parents:
diff
changeset
|
323 continue; /* count the bytes */ |
1308 | 324 while (n--) { |
325 len++; | |
326 if (d) *d++ = (n ? 0x80 : 0) | ((id >> (7*n)) & 0x7F); | |
327 } | |
4
fe6bca95afa7
Makefile.in contains updated files required
Matt Johnston <matt@ucc.asn.au>
parents:
diff
changeset
|
328 } |
fe6bca95afa7
Makefile.in contains updated files required
Matt Johnston <matt@ucc.asn.au>
parents:
diff
changeset
|
329 |
1308 | 330 if (length < 128) { |
331 /* | |
332 * Length is one byte. | |
333 */ | |
334 len++; | |
335 if (d) *d++ = length; | |
336 } else { | |
337 int n; | |
338 /* | |
339 * Length is multiple bytes. The first is 0x80 plus the | |
340 * number of subsequent bytes, and the subsequent bytes | |
341 * encode the actual length. | |
342 */ | |
343 for (n = 1; (length >> (8*n)) > 0; n++) | |
4
fe6bca95afa7
Makefile.in contains updated files required
Matt Johnston <matt@ucc.asn.au>
parents:
diff
changeset
|
344 continue; /* count the bytes */ |
1308 | 345 len++; |
346 if (d) *d++ = 0x80 | n; | |
347 while (n--) { | |
348 len++; | |
349 if (d) *d++ = (length >> (8*n)) & 0xFF; | |
350 } | |
4
fe6bca95afa7
Makefile.in contains updated files required
Matt Johnston <matt@ucc.asn.au>
parents:
diff
changeset
|
351 } |
fe6bca95afa7
Makefile.in contains updated files required
Matt Johnston <matt@ucc.asn.au>
parents:
diff
changeset
|
352 |
1308 | 353 return len; |
4
fe6bca95afa7
Makefile.in contains updated files required
Matt Johnston <matt@ucc.asn.au>
parents:
diff
changeset
|
354 } |
fe6bca95afa7
Makefile.in contains updated files required
Matt Johnston <matt@ucc.asn.au>
parents:
diff
changeset
|
355 |
fe6bca95afa7
Makefile.in contains updated files required
Matt Johnston <matt@ucc.asn.au>
parents:
diff
changeset
|
356 |
fe6bca95afa7
Makefile.in contains updated files required
Matt Johnston <matt@ucc.asn.au>
parents:
diff
changeset
|
357 /* Simple structure to point to an mp-int within a blob. */ |
fe6bca95afa7
Makefile.in contains updated files required
Matt Johnston <matt@ucc.asn.au>
parents:
diff
changeset
|
358 struct mpint_pos { void *start; int bytes; }; |
fe6bca95afa7
Makefile.in contains updated files required
Matt Johnston <matt@ucc.asn.au>
parents:
diff
changeset
|
359 |
fe6bca95afa7
Makefile.in contains updated files required
Matt Johnston <matt@ucc.asn.au>
parents:
diff
changeset
|
360 /* ---------------------------------------------------------------------- |
fe6bca95afa7
Makefile.in contains updated files required
Matt Johnston <matt@ucc.asn.au>
parents:
diff
changeset
|
361 * Code to read and write OpenSSH private keys. |
fe6bca95afa7
Makefile.in contains updated files required
Matt Johnston <matt@ucc.asn.au>
parents:
diff
changeset
|
362 */ |
fe6bca95afa7
Makefile.in contains updated files required
Matt Johnston <matt@ucc.asn.au>
parents:
diff
changeset
|
363 |
1659
d32bcb5c557d
Add Ed25519 support (#91)
Vladislav Grishenko <themiron@users.noreply.github.com>
parents:
1638
diff
changeset
|
364 enum { OSSH_DSA, OSSH_RSA, OSSH_EC, OSSH_PKEY }; |
4
fe6bca95afa7
Makefile.in contains updated files required
Matt Johnston <matt@ucc.asn.au>
parents:
diff
changeset
|
365 struct openssh_key { |
1308 | 366 int type; |
367 int encrypted; | |
368 char iv[32]; | |
369 unsigned char *keyblob; | |
4
fe6bca95afa7
Makefile.in contains updated files required
Matt Johnston <matt@ucc.asn.au>
parents:
diff
changeset
|
370 unsigned int keyblob_len, keyblob_size; |
fe6bca95afa7
Makefile.in contains updated files required
Matt Johnston <matt@ucc.asn.au>
parents:
diff
changeset
|
371 }; |
fe6bca95afa7
Makefile.in contains updated files required
Matt Johnston <matt@ucc.asn.au>
parents:
diff
changeset
|
372 |
fe6bca95afa7
Makefile.in contains updated files required
Matt Johnston <matt@ucc.asn.au>
parents:
diff
changeset
|
373 static struct openssh_key *load_openssh_key(const char *filename) |
fe6bca95afa7
Makefile.in contains updated files required
Matt Johnston <matt@ucc.asn.au>
parents:
diff
changeset
|
374 { |
1308 | 375 struct openssh_key *ret; |
1659
d32bcb5c557d
Add Ed25519 support (#91)
Vladislav Grishenko <themiron@users.noreply.github.com>
parents:
1638
diff
changeset
|
376 buffer *buf = NULL; |
340 | 377 FILE *fp = NULL; |
1308 | 378 char buffer[256]; |
4
fe6bca95afa7
Makefile.in contains updated files required
Matt Johnston <matt@ucc.asn.au>
parents:
diff
changeset
|
379 char *errmsg = NULL, *p = NULL; |
1308 | 380 int headers_done; |
1659
d32bcb5c557d
Add Ed25519 support (#91)
Vladislav Grishenko <themiron@users.noreply.github.com>
parents:
1638
diff
changeset
|
381 unsigned long len; |
4
fe6bca95afa7
Makefile.in contains updated files required
Matt Johnston <matt@ucc.asn.au>
parents:
diff
changeset
|
382 |
fe6bca95afa7
Makefile.in contains updated files required
Matt Johnston <matt@ucc.asn.au>
parents:
diff
changeset
|
383 ret = (struct openssh_key*)m_malloc(sizeof(struct openssh_key)); |
1308 | 384 ret->keyblob = NULL; |
385 ret->keyblob_len = ret->keyblob_size = 0; | |
386 ret->encrypted = 0; | |
387 memset(ret->iv, 0, sizeof(ret->iv)); | |
4
fe6bca95afa7
Makefile.in contains updated files required
Matt Johnston <matt@ucc.asn.au>
parents:
diff
changeset
|
388 |
fe6bca95afa7
Makefile.in contains updated files required
Matt Johnston <matt@ucc.asn.au>
parents:
diff
changeset
|
389 if (strlen(filename) == 1 && filename[0] == '-') { |
fe6bca95afa7
Makefile.in contains updated files required
Matt Johnston <matt@ucc.asn.au>
parents:
diff
changeset
|
390 fp = stdin; |
fe6bca95afa7
Makefile.in contains updated files required
Matt Johnston <matt@ucc.asn.au>
parents:
diff
changeset
|
391 } else { |
fe6bca95afa7
Makefile.in contains updated files required
Matt Johnston <matt@ucc.asn.au>
parents:
diff
changeset
|
392 fp = fopen(filename, "r"); |
fe6bca95afa7
Makefile.in contains updated files required
Matt Johnston <matt@ucc.asn.au>
parents:
diff
changeset
|
393 } |
1308 | 394 if (!fp) { |
395 errmsg = "Unable to open key file"; | |
396 goto error; | |
1306
34e6127ef02e
merge fixes from PuTTY import.c
Matt Johnston <matt@ucc.asn.au>
parents:
1250
diff
changeset
|
397 } |
1308 | 398 if (!fgets(buffer, sizeof(buffer), fp) || |
399 0 != strncmp(buffer, "-----BEGIN ", 11) || | |
400 0 != strcmp(buffer+strlen(buffer)-17, "PRIVATE KEY-----\n")) { | |
401 errmsg = "File does not begin with OpenSSH key header"; | |
1306
34e6127ef02e
merge fixes from PuTTY import.c
Matt Johnston <matt@ucc.asn.au>
parents:
1250
diff
changeset
|
402 goto error; |
1308 | 403 } |
404 if (!strcmp(buffer, "-----BEGIN RSA PRIVATE KEY-----\n")) | |
405 ret->type = OSSH_RSA; | |
406 else if (!strcmp(buffer, "-----BEGIN DSA PRIVATE KEY-----\n")) | |
407 ret->type = OSSH_DSA; | |
793
70625eed40c9
A bit of work on ecdsa for host/auth keys
Matt Johnston <matt@ucc.asn.au>
parents:
491
diff
changeset
|
408 else if (!strcmp(buffer, "-----BEGIN EC PRIVATE KEY-----\n")) |
70625eed40c9
A bit of work on ecdsa for host/auth keys
Matt Johnston <matt@ucc.asn.au>
parents:
491
diff
changeset
|
409 ret->type = OSSH_EC; |
1659
d32bcb5c557d
Add Ed25519 support (#91)
Vladislav Grishenko <themiron@users.noreply.github.com>
parents:
1638
diff
changeset
|
410 else if (!strcmp(buffer, "-----BEGIN OPENSSH PRIVATE KEY-----\n")) |
d32bcb5c557d
Add Ed25519 support (#91)
Vladislav Grishenko <themiron@users.noreply.github.com>
parents:
1638
diff
changeset
|
411 ret->type = OSSH_PKEY; |
1308 | 412 else { |
413 errmsg = "Unrecognised key type"; | |
414 goto error; | |
4
fe6bca95afa7
Makefile.in contains updated files required
Matt Johnston <matt@ucc.asn.au>
parents:
diff
changeset
|
415 } |
fe6bca95afa7
Makefile.in contains updated files required
Matt Johnston <matt@ucc.asn.au>
parents:
diff
changeset
|
416 |
1308 | 417 headers_done = 0; |
1659
d32bcb5c557d
Add Ed25519 support (#91)
Vladislav Grishenko <themiron@users.noreply.github.com>
parents:
1638
diff
changeset
|
418 buf = buf_new(0); |
1308 | 419 while (1) { |
420 if (!fgets(buffer, sizeof(buffer), fp)) { | |
421 errmsg = "Unexpected end of file"; | |
422 goto error; | |
423 } | |
424 if (0 == strncmp(buffer, "-----END ", 9) && | |
425 0 == strcmp(buffer+strlen(buffer)-17, "PRIVATE KEY-----\n")) | |
4
fe6bca95afa7
Makefile.in contains updated files required
Matt Johnston <matt@ucc.asn.au>
parents:
diff
changeset
|
426 break; /* done */ |
1308 | 427 if ((p = strchr(buffer, ':')) != NULL) { |
428 if (headers_done) { | |
429 errmsg = "Header found in body of key data"; | |
430 goto error; | |
431 } | |
432 *p++ = '\0'; | |
433 while (*p && isspace((unsigned char)*p)) p++; | |
434 if (!strcmp(buffer, "Proc-Type")) { | |
435 if (p[0] != '4' || p[1] != ',') { | |
436 errmsg = "Proc-Type is not 4 (only 4 is supported)"; | |
437 goto error; | |
438 } | |
439 p += 2; | |
440 if (!strcmp(p, "ENCRYPTED\n")) | |
441 ret->encrypted = 1; | |
442 } else if (!strcmp(buffer, "DEK-Info")) { | |
443 int i, j; | |
1306
34e6127ef02e
merge fixes from PuTTY import.c
Matt Johnston <matt@ucc.asn.au>
parents:
1250
diff
changeset
|
444 |
1308 | 445 if (strncmp(p, "DES-EDE3-CBC,", 13)) { |
446 errmsg = "Ciphers other than DES-EDE3-CBC not supported"; | |
447 goto error; | |
448 } | |
449 p += 13; | |
450 for (i = 0; i < 8; i++) { | |
451 if (1 != sscanf(p, "%2x", &j)) | |
452 break; | |
453 ret->iv[i] = j; | |
454 p += 2; | |
455 } | |
456 if (i < 8) { | |
457 errmsg = "Expected 16-digit iv in DEK-Info"; | |
458 goto error; | |
459 } | |
460 } | |
461 } else { | |
462 headers_done = 1; | |
4
fe6bca95afa7
Makefile.in contains updated files required
Matt Johnston <matt@ucc.asn.au>
parents:
diff
changeset
|
463 len = strlen(buffer); |
1659
d32bcb5c557d
Add Ed25519 support (#91)
Vladislav Grishenko <themiron@users.noreply.github.com>
parents:
1638
diff
changeset
|
464 buf = buf_resize(buf, buf->size + len); |
d32bcb5c557d
Add Ed25519 support (#91)
Vladislav Grishenko <themiron@users.noreply.github.com>
parents:
1638
diff
changeset
|
465 buf_putbytes(buf, buffer, len); |
1308 | 466 } |
4
fe6bca95afa7
Makefile.in contains updated files required
Matt Johnston <matt@ucc.asn.au>
parents:
diff
changeset
|
467 } |
1308 | 468 |
1659
d32bcb5c557d
Add Ed25519 support (#91)
Vladislav Grishenko <themiron@users.noreply.github.com>
parents:
1638
diff
changeset
|
469 if (buf && buf->len) { |
d32bcb5c557d
Add Ed25519 support (#91)
Vladislav Grishenko <themiron@users.noreply.github.com>
parents:
1638
diff
changeset
|
470 ret->keyblob_size = ret->keyblob_len + buf->len*4/3 + 256; |
d32bcb5c557d
Add Ed25519 support (#91)
Vladislav Grishenko <themiron@users.noreply.github.com>
parents:
1638
diff
changeset
|
471 ret->keyblob = (unsigned char*)m_realloc(ret->keyblob, ret->keyblob_size); |
d32bcb5c557d
Add Ed25519 support (#91)
Vladislav Grishenko <themiron@users.noreply.github.com>
parents:
1638
diff
changeset
|
472 len = ret->keyblob_size; |
d32bcb5c557d
Add Ed25519 support (#91)
Vladislav Grishenko <themiron@users.noreply.github.com>
parents:
1638
diff
changeset
|
473 if (base64_decode((const unsigned char *)buf->data, buf->len, |
d32bcb5c557d
Add Ed25519 support (#91)
Vladislav Grishenko <themiron@users.noreply.github.com>
parents:
1638
diff
changeset
|
474 ret->keyblob, &len) != CRYPT_OK){ |
d32bcb5c557d
Add Ed25519 support (#91)
Vladislav Grishenko <themiron@users.noreply.github.com>
parents:
1638
diff
changeset
|
475 errmsg = "Error decoding base64"; |
d32bcb5c557d
Add Ed25519 support (#91)
Vladislav Grishenko <themiron@users.noreply.github.com>
parents:
1638
diff
changeset
|
476 goto error; |
d32bcb5c557d
Add Ed25519 support (#91)
Vladislav Grishenko <themiron@users.noreply.github.com>
parents:
1638
diff
changeset
|
477 } |
d32bcb5c557d
Add Ed25519 support (#91)
Vladislav Grishenko <themiron@users.noreply.github.com>
parents:
1638
diff
changeset
|
478 ret->keyblob_len = len; |
d32bcb5c557d
Add Ed25519 support (#91)
Vladislav Grishenko <themiron@users.noreply.github.com>
parents:
1638
diff
changeset
|
479 } |
d32bcb5c557d
Add Ed25519 support (#91)
Vladislav Grishenko <themiron@users.noreply.github.com>
parents:
1638
diff
changeset
|
480 |
d32bcb5c557d
Add Ed25519 support (#91)
Vladislav Grishenko <themiron@users.noreply.github.com>
parents:
1638
diff
changeset
|
481 if (ret->type == OSSH_PKEY) { |
d32bcb5c557d
Add Ed25519 support (#91)
Vladislav Grishenko <themiron@users.noreply.github.com>
parents:
1638
diff
changeset
|
482 if (ret->keyblob_len < OSSH_PKEY_BLOBLEN || |
d32bcb5c557d
Add Ed25519 support (#91)
Vladislav Grishenko <themiron@users.noreply.github.com>
parents:
1638
diff
changeset
|
483 memcmp(ret->keyblob, OSSH_PKEY_BLOB, OSSH_PKEY_BLOBLEN)) { |
d32bcb5c557d
Add Ed25519 support (#91)
Vladislav Grishenko <themiron@users.noreply.github.com>
parents:
1638
diff
changeset
|
484 errmsg = "Error decoding OpenSSH key"; |
d32bcb5c557d
Add Ed25519 support (#91)
Vladislav Grishenko <themiron@users.noreply.github.com>
parents:
1638
diff
changeset
|
485 goto error; |
d32bcb5c557d
Add Ed25519 support (#91)
Vladislav Grishenko <themiron@users.noreply.github.com>
parents:
1638
diff
changeset
|
486 } |
d32bcb5c557d
Add Ed25519 support (#91)
Vladislav Grishenko <themiron@users.noreply.github.com>
parents:
1638
diff
changeset
|
487 ret->keyblob_len -= OSSH_PKEY_BLOBLEN; |
d32bcb5c557d
Add Ed25519 support (#91)
Vladislav Grishenko <themiron@users.noreply.github.com>
parents:
1638
diff
changeset
|
488 memmove(ret->keyblob, ret->keyblob + OSSH_PKEY_BLOBLEN, ret->keyblob_len); |
d32bcb5c557d
Add Ed25519 support (#91)
Vladislav Grishenko <themiron@users.noreply.github.com>
parents:
1638
diff
changeset
|
489 } |
d32bcb5c557d
Add Ed25519 support (#91)
Vladislav Grishenko <themiron@users.noreply.github.com>
parents:
1638
diff
changeset
|
490 |
1308 | 491 if (ret->keyblob_len == 0 || !ret->keyblob) { |
492 errmsg = "Key body not present"; | |
493 goto error; | |
494 } | |
495 | |
496 if (ret->encrypted && ret->keyblob_len % 8 != 0) { | |
497 errmsg = "Encrypted key blob is not a multiple of cipher block size"; | |
498 goto error; | |
499 } | |
4
fe6bca95afa7
Makefile.in contains updated files required
Matt Johnston <matt@ucc.asn.au>
parents:
diff
changeset
|
500 |
1659
d32bcb5c557d
Add Ed25519 support (#91)
Vladislav Grishenko <themiron@users.noreply.github.com>
parents:
1638
diff
changeset
|
501 if (buf) { |
d32bcb5c557d
Add Ed25519 support (#91)
Vladislav Grishenko <themiron@users.noreply.github.com>
parents:
1638
diff
changeset
|
502 buf_burn(buf); |
d32bcb5c557d
Add Ed25519 support (#91)
Vladislav Grishenko <themiron@users.noreply.github.com>
parents:
1638
diff
changeset
|
503 buf_free(buf); |
d32bcb5c557d
Add Ed25519 support (#91)
Vladislav Grishenko <themiron@users.noreply.github.com>
parents:
1638
diff
changeset
|
504 } |
1045
31727a8abd4b
Use m_burn rather than memset
Thorsten Horstmann <thorsten.horstmann@web.de>
parents:
1038
diff
changeset
|
505 m_burn(buffer, sizeof(buffer)); |
1308 | 506 return ret; |
4
fe6bca95afa7
Makefile.in contains updated files required
Matt Johnston <matt@ucc.asn.au>
parents:
diff
changeset
|
507 |
1308 | 508 error: |
1659
d32bcb5c557d
Add Ed25519 support (#91)
Vladislav Grishenko <themiron@users.noreply.github.com>
parents:
1638
diff
changeset
|
509 if (buf) { |
d32bcb5c557d
Add Ed25519 support (#91)
Vladislav Grishenko <themiron@users.noreply.github.com>
parents:
1638
diff
changeset
|
510 buf_burn(buf); |
d32bcb5c557d
Add Ed25519 support (#91)
Vladislav Grishenko <themiron@users.noreply.github.com>
parents:
1638
diff
changeset
|
511 buf_free(buf); |
d32bcb5c557d
Add Ed25519 support (#91)
Vladislav Grishenko <themiron@users.noreply.github.com>
parents:
1638
diff
changeset
|
512 } |
1045
31727a8abd4b
Use m_burn rather than memset
Thorsten Horstmann <thorsten.horstmann@web.de>
parents:
1038
diff
changeset
|
513 m_burn(buffer, sizeof(buffer)); |
1308 | 514 if (ret) { |
515 if (ret->keyblob) { | |
1045
31727a8abd4b
Use m_burn rather than memset
Thorsten Horstmann <thorsten.horstmann@web.de>
parents:
1038
diff
changeset
|
516 m_burn(ret->keyblob, ret->keyblob_size); |
4
fe6bca95afa7
Makefile.in contains updated files required
Matt Johnston <matt@ucc.asn.au>
parents:
diff
changeset
|
517 m_free(ret->keyblob); |
1308 | 518 } |
4
fe6bca95afa7
Makefile.in contains updated files required
Matt Johnston <matt@ucc.asn.au>
parents:
diff
changeset
|
519 m_free(ret); |
fe6bca95afa7
Makefile.in contains updated files required
Matt Johnston <matt@ucc.asn.au>
parents:
diff
changeset
|
520 } |
340 | 521 if (fp) { |
522 fclose(fp); | |
1308 | 523 } |
4
fe6bca95afa7
Makefile.in contains updated files required
Matt Johnston <matt@ucc.asn.au>
parents:
diff
changeset
|
524 if (errmsg) { |
fe6bca95afa7
Makefile.in contains updated files required
Matt Johnston <matt@ucc.asn.au>
parents:
diff
changeset
|
525 fprintf(stderr, "Error: %s\n", errmsg); |
fe6bca95afa7
Makefile.in contains updated files required
Matt Johnston <matt@ucc.asn.au>
parents:
diff
changeset
|
526 } |
1308 | 527 return NULL; |
4
fe6bca95afa7
Makefile.in contains updated files required
Matt Johnston <matt@ucc.asn.au>
parents:
diff
changeset
|
528 } |
fe6bca95afa7
Makefile.in contains updated files required
Matt Johnston <matt@ucc.asn.au>
parents:
diff
changeset
|
529 |
fe6bca95afa7
Makefile.in contains updated files required
Matt Johnston <matt@ucc.asn.au>
parents:
diff
changeset
|
530 static int openssh_encrypted(const char *filename) |
fe6bca95afa7
Makefile.in contains updated files required
Matt Johnston <matt@ucc.asn.au>
parents:
diff
changeset
|
531 { |
1308 | 532 struct openssh_key *key = load_openssh_key(filename); |
533 int ret; | |
4
fe6bca95afa7
Makefile.in contains updated files required
Matt Johnston <matt@ucc.asn.au>
parents:
diff
changeset
|
534 |
1308 | 535 if (!key) |
536 return 0; | |
537 ret = key->encrypted; | |
1045
31727a8abd4b
Use m_burn rather than memset
Thorsten Horstmann <thorsten.horstmann@web.de>
parents:
1038
diff
changeset
|
538 m_burn(key->keyblob, key->keyblob_size); |
4
fe6bca95afa7
Makefile.in contains updated files required
Matt Johnston <matt@ucc.asn.au>
parents:
diff
changeset
|
539 m_free(key->keyblob); |
fe6bca95afa7
Makefile.in contains updated files required
Matt Johnston <matt@ucc.asn.au>
parents:
diff
changeset
|
540 m_free(key); |
1308 | 541 return ret; |
4
fe6bca95afa7
Makefile.in contains updated files required
Matt Johnston <matt@ucc.asn.au>
parents:
diff
changeset
|
542 } |
fe6bca95afa7
Makefile.in contains updated files required
Matt Johnston <matt@ucc.asn.au>
parents:
diff
changeset
|
543 |
1459
06d52bcb8094
Pointer parameter could be declared as pointing to const
Francois Perrad <francois.perrad@gadz.org>
parents:
1395
diff
changeset
|
544 static sign_key *openssh_read(const char *filename, const char * UNUSED(passphrase)) |
4
fe6bca95afa7
Makefile.in contains updated files required
Matt Johnston <matt@ucc.asn.au>
parents:
diff
changeset
|
545 { |
fe6bca95afa7
Makefile.in contains updated files required
Matt Johnston <matt@ucc.asn.au>
parents:
diff
changeset
|
546 struct openssh_key *key; |
1308 | 547 unsigned char *p; |
548 int ret, id, len, flags; | |
4
fe6bca95afa7
Makefile.in contains updated files required
Matt Johnston <matt@ucc.asn.au>
parents:
diff
changeset
|
549 int i, num_integers = 0; |
fe6bca95afa7
Makefile.in contains updated files required
Matt Johnston <matt@ucc.asn.au>
parents:
diff
changeset
|
550 sign_key *retval = NULL; |
1308 | 551 char *errmsg; |
1119
845922d73e9c
Turn modptr local variable into unsigned char *
Gaël PORTAY <gael.portay@gmail.com>
parents:
1094
diff
changeset
|
552 unsigned char *modptr = NULL; |
4
fe6bca95afa7
Makefile.in contains updated files required
Matt Johnston <matt@ucc.asn.au>
parents:
diff
changeset
|
553 int modlen = -9999; |
846
b298bb438625
refactor key generation, make it generate as required.
Matt Johnston <matt@ucc.asn.au>
parents:
845
diff
changeset
|
554 enum signkey_type type; |
4
fe6bca95afa7
Makefile.in contains updated files required
Matt Johnston <matt@ucc.asn.au>
parents:
diff
changeset
|
555 |
fe6bca95afa7
Makefile.in contains updated files required
Matt Johnston <matt@ucc.asn.au>
parents:
diff
changeset
|
556 sign_key *retkey; |
fe6bca95afa7
Makefile.in contains updated files required
Matt Johnston <matt@ucc.asn.au>
parents:
diff
changeset
|
557 buffer * blobbuf = NULL; |
fe6bca95afa7
Makefile.in contains updated files required
Matt Johnston <matt@ucc.asn.au>
parents:
diff
changeset
|
558 |
806
71e7d31f7671
hackish ECC import code from OpenSSH
Matt Johnston <matt@ucc.asn.au>
parents:
793
diff
changeset
|
559 retkey = new_sign_key(); |
71e7d31f7671
hackish ECC import code from OpenSSH
Matt Johnston <matt@ucc.asn.au>
parents:
793
diff
changeset
|
560 |
4
fe6bca95afa7
Makefile.in contains updated files required
Matt Johnston <matt@ucc.asn.au>
parents:
diff
changeset
|
561 key = load_openssh_key(filename); |
fe6bca95afa7
Makefile.in contains updated files required
Matt Johnston <matt@ucc.asn.au>
parents:
diff
changeset
|
562 |
1308 | 563 if (!key) |
564 return NULL; | |
4
fe6bca95afa7
Makefile.in contains updated files required
Matt Johnston <matt@ucc.asn.au>
parents:
diff
changeset
|
565 |
1308 | 566 if (key->encrypted) { |
4
fe6bca95afa7
Makefile.in contains updated files required
Matt Johnston <matt@ucc.asn.au>
parents:
diff
changeset
|
567 errmsg = "encrypted keys not supported currently"; |
fe6bca95afa7
Makefile.in contains updated files required
Matt Johnston <matt@ucc.asn.au>
parents:
diff
changeset
|
568 goto error; |
fe6bca95afa7
Makefile.in contains updated files required
Matt Johnston <matt@ucc.asn.au>
parents:
diff
changeset
|
569 #if 0 |
fe6bca95afa7
Makefile.in contains updated files required
Matt Johnston <matt@ucc.asn.au>
parents:
diff
changeset
|
570 /* matt TODO */ |
1308 | 571 /* |
572 * Derive encryption key from passphrase and iv/salt: | |
573 * | |
574 * - let block A equal MD5(passphrase || iv) | |
575 * - let block B equal MD5(A || passphrase || iv) | |
576 * - block C would be MD5(B || passphrase || iv) and so on | |
577 * - encryption key is the first N bytes of A || B | |
578 */ | |
579 struct MD5Context md5c; | |
580 unsigned char keybuf[32]; | |
581 | |
582 MD5Init(&md5c); | |
583 MD5Update(&md5c, (unsigned char *)passphrase, strlen(passphrase)); | |
584 MD5Update(&md5c, (unsigned char *)key->iv, 8); | |
585 MD5Final(keybuf, &md5c); | |
4
fe6bca95afa7
Makefile.in contains updated files required
Matt Johnston <matt@ucc.asn.au>
parents:
diff
changeset
|
586 |
1308 | 587 MD5Init(&md5c); |
588 MD5Update(&md5c, keybuf, 16); | |
589 MD5Update(&md5c, (unsigned char *)passphrase, strlen(passphrase)); | |
590 MD5Update(&md5c, (unsigned char *)key->iv, 8); | |
591 MD5Final(keybuf+16, &md5c); | |
4
fe6bca95afa7
Makefile.in contains updated files required
Matt Johnston <matt@ucc.asn.au>
parents:
diff
changeset
|
592 |
1308 | 593 /* |
594 * Now decrypt the key blob. | |
595 */ | |
596 des3_decrypt_pubkey_ossh(keybuf, (unsigned char *)key->iv, | |
597 key->keyblob, key->keyblob_len); | |
598 | |
599 memset(&md5c, 0, sizeof(md5c)); | |
600 memset(keybuf, 0, sizeof(keybuf)); | |
601 #endif | |
602 } | |
4
fe6bca95afa7
Makefile.in contains updated files required
Matt Johnston <matt@ucc.asn.au>
parents:
diff
changeset
|
603 |
fe6bca95afa7
Makefile.in contains updated files required
Matt Johnston <matt@ucc.asn.au>
parents:
diff
changeset
|
604 /* |
1659
d32bcb5c557d
Add Ed25519 support (#91)
Vladislav Grishenko <themiron@users.noreply.github.com>
parents:
1638
diff
changeset
|
605 * Now we have a decrypted key blob, which contains OpenSSH |
d32bcb5c557d
Add Ed25519 support (#91)
Vladislav Grishenko <themiron@users.noreply.github.com>
parents:
1638
diff
changeset
|
606 * encoded private key. We must now untangle the OpenSSH format. |
d32bcb5c557d
Add Ed25519 support (#91)
Vladislav Grishenko <themiron@users.noreply.github.com>
parents:
1638
diff
changeset
|
607 */ |
d32bcb5c557d
Add Ed25519 support (#91)
Vladislav Grishenko <themiron@users.noreply.github.com>
parents:
1638
diff
changeset
|
608 if (key->type == OSSH_PKEY) { |
d32bcb5c557d
Add Ed25519 support (#91)
Vladislav Grishenko <themiron@users.noreply.github.com>
parents:
1638
diff
changeset
|
609 blobbuf = buf_new(key->keyblob_len); |
d32bcb5c557d
Add Ed25519 support (#91)
Vladislav Grishenko <themiron@users.noreply.github.com>
parents:
1638
diff
changeset
|
610 buf_putbytes(blobbuf, key->keyblob, key->keyblob_len); |
d32bcb5c557d
Add Ed25519 support (#91)
Vladislav Grishenko <themiron@users.noreply.github.com>
parents:
1638
diff
changeset
|
611 buf_setpos(blobbuf, 0); |
d32bcb5c557d
Add Ed25519 support (#91)
Vladislav Grishenko <themiron@users.noreply.github.com>
parents:
1638
diff
changeset
|
612 |
d32bcb5c557d
Add Ed25519 support (#91)
Vladislav Grishenko <themiron@users.noreply.github.com>
parents:
1638
diff
changeset
|
613 /* limit length of private key blob */ |
d32bcb5c557d
Add Ed25519 support (#91)
Vladislav Grishenko <themiron@users.noreply.github.com>
parents:
1638
diff
changeset
|
614 len = buf_getint(blobbuf); |
d32bcb5c557d
Add Ed25519 support (#91)
Vladislav Grishenko <themiron@users.noreply.github.com>
parents:
1638
diff
changeset
|
615 buf_setlen(blobbuf, blobbuf->pos + len); |
d32bcb5c557d
Add Ed25519 support (#91)
Vladislav Grishenko <themiron@users.noreply.github.com>
parents:
1638
diff
changeset
|
616 |
d32bcb5c557d
Add Ed25519 support (#91)
Vladislav Grishenko <themiron@users.noreply.github.com>
parents:
1638
diff
changeset
|
617 type = DROPBEAR_SIGNKEY_ANY; |
d32bcb5c557d
Add Ed25519 support (#91)
Vladislav Grishenko <themiron@users.noreply.github.com>
parents:
1638
diff
changeset
|
618 if (buf_get_pub_key(blobbuf, retkey, &type) |
d32bcb5c557d
Add Ed25519 support (#91)
Vladislav Grishenko <themiron@users.noreply.github.com>
parents:
1638
diff
changeset
|
619 != DROPBEAR_SUCCESS) { |
d32bcb5c557d
Add Ed25519 support (#91)
Vladislav Grishenko <themiron@users.noreply.github.com>
parents:
1638
diff
changeset
|
620 errmsg = "Error parsing OpenSSH key"; |
d32bcb5c557d
Add Ed25519 support (#91)
Vladislav Grishenko <themiron@users.noreply.github.com>
parents:
1638
diff
changeset
|
621 goto ossh_error; |
d32bcb5c557d
Add Ed25519 support (#91)
Vladislav Grishenko <themiron@users.noreply.github.com>
parents:
1638
diff
changeset
|
622 } |
d32bcb5c557d
Add Ed25519 support (#91)
Vladislav Grishenko <themiron@users.noreply.github.com>
parents:
1638
diff
changeset
|
623 |
d32bcb5c557d
Add Ed25519 support (#91)
Vladislav Grishenko <themiron@users.noreply.github.com>
parents:
1638
diff
changeset
|
624 /* restore full length */ |
d32bcb5c557d
Add Ed25519 support (#91)
Vladislav Grishenko <themiron@users.noreply.github.com>
parents:
1638
diff
changeset
|
625 buf_setlen(blobbuf, key->keyblob_len); |
d32bcb5c557d
Add Ed25519 support (#91)
Vladislav Grishenko <themiron@users.noreply.github.com>
parents:
1638
diff
changeset
|
626 |
d32bcb5c557d
Add Ed25519 support (#91)
Vladislav Grishenko <themiron@users.noreply.github.com>
parents:
1638
diff
changeset
|
627 if (type != DROPBEAR_SIGNKEY_NONE) { |
d32bcb5c557d
Add Ed25519 support (#91)
Vladislav Grishenko <themiron@users.noreply.github.com>
parents:
1638
diff
changeset
|
628 retkey->type = type; |
d32bcb5c557d
Add Ed25519 support (#91)
Vladislav Grishenko <themiron@users.noreply.github.com>
parents:
1638
diff
changeset
|
629 /* limit length of private key blob */ |
d32bcb5c557d
Add Ed25519 support (#91)
Vladislav Grishenko <themiron@users.noreply.github.com>
parents:
1638
diff
changeset
|
630 len = buf_getint(blobbuf); |
d32bcb5c557d
Add Ed25519 support (#91)
Vladislav Grishenko <themiron@users.noreply.github.com>
parents:
1638
diff
changeset
|
631 buf_setlen(blobbuf, blobbuf->pos + len); |
d32bcb5c557d
Add Ed25519 support (#91)
Vladislav Grishenko <themiron@users.noreply.github.com>
parents:
1638
diff
changeset
|
632 #if DROPBEAR_ED25519 |
d32bcb5c557d
Add Ed25519 support (#91)
Vladislav Grishenko <themiron@users.noreply.github.com>
parents:
1638
diff
changeset
|
633 if (type == DROPBEAR_SIGNKEY_ED25519) { |
d32bcb5c557d
Add Ed25519 support (#91)
Vladislav Grishenko <themiron@users.noreply.github.com>
parents:
1638
diff
changeset
|
634 buf_incrpos(blobbuf, 8); |
d32bcb5c557d
Add Ed25519 support (#91)
Vladislav Grishenko <themiron@users.noreply.github.com>
parents:
1638
diff
changeset
|
635 buf_eatstring(blobbuf); |
d32bcb5c557d
Add Ed25519 support (#91)
Vladislav Grishenko <themiron@users.noreply.github.com>
parents:
1638
diff
changeset
|
636 buf_eatstring(blobbuf); |
d32bcb5c557d
Add Ed25519 support (#91)
Vladislav Grishenko <themiron@users.noreply.github.com>
parents:
1638
diff
changeset
|
637 buf_incrpos(blobbuf, -SSH_SIGNKEY_ED25519_LEN-4); |
d32bcb5c557d
Add Ed25519 support (#91)
Vladislav Grishenko <themiron@users.noreply.github.com>
parents:
1638
diff
changeset
|
638 if (buf_get_ed25519_priv_key(blobbuf, retkey->ed25519key) |
d32bcb5c557d
Add Ed25519 support (#91)
Vladislav Grishenko <themiron@users.noreply.github.com>
parents:
1638
diff
changeset
|
639 == DROPBEAR_SUCCESS) { |
d32bcb5c557d
Add Ed25519 support (#91)
Vladislav Grishenko <themiron@users.noreply.github.com>
parents:
1638
diff
changeset
|
640 errmsg = NULL; |
d32bcb5c557d
Add Ed25519 support (#91)
Vladislav Grishenko <themiron@users.noreply.github.com>
parents:
1638
diff
changeset
|
641 retval = retkey; |
d32bcb5c557d
Add Ed25519 support (#91)
Vladislav Grishenko <themiron@users.noreply.github.com>
parents:
1638
diff
changeset
|
642 goto error; |
d32bcb5c557d
Add Ed25519 support (#91)
Vladislav Grishenko <themiron@users.noreply.github.com>
parents:
1638
diff
changeset
|
643 } |
d32bcb5c557d
Add Ed25519 support (#91)
Vladislav Grishenko <themiron@users.noreply.github.com>
parents:
1638
diff
changeset
|
644 } |
d32bcb5c557d
Add Ed25519 support (#91)
Vladislav Grishenko <themiron@users.noreply.github.com>
parents:
1638
diff
changeset
|
645 #endif |
d32bcb5c557d
Add Ed25519 support (#91)
Vladislav Grishenko <themiron@users.noreply.github.com>
parents:
1638
diff
changeset
|
646 } |
d32bcb5c557d
Add Ed25519 support (#91)
Vladislav Grishenko <themiron@users.noreply.github.com>
parents:
1638
diff
changeset
|
647 |
d32bcb5c557d
Add Ed25519 support (#91)
Vladislav Grishenko <themiron@users.noreply.github.com>
parents:
1638
diff
changeset
|
648 errmsg = "Unsupported OpenSSH key type"; |
d32bcb5c557d
Add Ed25519 support (#91)
Vladislav Grishenko <themiron@users.noreply.github.com>
parents:
1638
diff
changeset
|
649 ossh_error: |
d32bcb5c557d
Add Ed25519 support (#91)
Vladislav Grishenko <themiron@users.noreply.github.com>
parents:
1638
diff
changeset
|
650 sign_key_free(retkey); |
d32bcb5c557d
Add Ed25519 support (#91)
Vladislav Grishenko <themiron@users.noreply.github.com>
parents:
1638
diff
changeset
|
651 retkey = NULL; |
d32bcb5c557d
Add Ed25519 support (#91)
Vladislav Grishenko <themiron@users.noreply.github.com>
parents:
1638
diff
changeset
|
652 goto error; |
d32bcb5c557d
Add Ed25519 support (#91)
Vladislav Grishenko <themiron@users.noreply.github.com>
parents:
1638
diff
changeset
|
653 } |
d32bcb5c557d
Add Ed25519 support (#91)
Vladislav Grishenko <themiron@users.noreply.github.com>
parents:
1638
diff
changeset
|
654 |
d32bcb5c557d
Add Ed25519 support (#91)
Vladislav Grishenko <themiron@users.noreply.github.com>
parents:
1638
diff
changeset
|
655 /* |
1308 | 656 * Now we have a decrypted key blob, which contains an ASN.1 |
657 * encoded private key. We must now untangle the ASN.1. | |
658 * | |
659 * We expect the whole key blob to be formatted as a SEQUENCE | |
660 * (0x30 followed by a length code indicating that the rest of | |
661 * the blob is part of the sequence). Within that SEQUENCE we | |
662 * expect to see a bunch of INTEGERs. What those integers mean | |
663 * depends on the key type: | |
664 * | |
665 * - For RSA, we expect the integers to be 0, n, e, d, p, q, | |
4
fe6bca95afa7
Makefile.in contains updated files required
Matt Johnston <matt@ucc.asn.au>
parents:
diff
changeset
|
666 * dmp1, dmq1, iqmp in that order. (The last three are d mod |
fe6bca95afa7
Makefile.in contains updated files required
Matt Johnston <matt@ucc.asn.au>
parents:
diff
changeset
|
667 * (p-1), d mod (q-1), inverse of q mod p respectively.) |
1308 | 668 * |
669 * - For DSA, we expect them to be 0, p, q, g, y, x in that | |
4
fe6bca95afa7
Makefile.in contains updated files required
Matt Johnston <matt@ucc.asn.au>
parents:
diff
changeset
|
670 * order. |
fe6bca95afa7
Makefile.in contains updated files required
Matt Johnston <matt@ucc.asn.au>
parents:
diff
changeset
|
671 */ |
1308 | 672 |
673 p = key->keyblob; | |
4
fe6bca95afa7
Makefile.in contains updated files required
Matt Johnston <matt@ucc.asn.au>
parents:
diff
changeset
|
674 |
1308 | 675 /* Expect the SEQUENCE header. Take its absence as a failure to decrypt. */ |
676 ret = ber_read_id_len(p, key->keyblob_len, &id, &len, &flags); | |
677 p += ret; | |
678 if (ret < 0 || id != 16 || len < 0 || | |
679 key->keyblob+key->keyblob_len-p < len) { | |
680 errmsg = "ASN.1 decoding failure"; | |
681 goto error; | |
682 } | |
1306
34e6127ef02e
merge fixes from PuTTY import.c
Matt Johnston <matt@ucc.asn.au>
parents:
1250
diff
changeset
|
683 |
1308 | 684 /* Expect a load of INTEGERs. */ |
685 if (key->type == OSSH_RSA) | |
686 num_integers = 9; | |
687 else if (key->type == OSSH_DSA) | |
688 num_integers = 6; | |
806
71e7d31f7671
hackish ECC import code from OpenSSH
Matt Johnston <matt@ucc.asn.au>
parents:
793
diff
changeset
|
689 else if (key->type == OSSH_EC) |
71e7d31f7671
hackish ECC import code from OpenSSH
Matt Johnston <matt@ucc.asn.au>
parents:
793
diff
changeset
|
690 num_integers = 1; |
4
fe6bca95afa7
Makefile.in contains updated files required
Matt Johnston <matt@ucc.asn.au>
parents:
diff
changeset
|
691 |
1308 | 692 /* |
693 * Space to create key blob in. | |
694 */ | |
4
fe6bca95afa7
Makefile.in contains updated files required
Matt Johnston <matt@ucc.asn.au>
parents:
diff
changeset
|
695 blobbuf = buf_new(3000); |
fe6bca95afa7
Makefile.in contains updated files required
Matt Johnston <matt@ucc.asn.au>
parents:
diff
changeset
|
696 |
1295
750ec4ec4cbe
Convert #ifdef to #if, other build changes
Matt Johnston <matt@ucc.asn.au>
parents:
1294
diff
changeset
|
697 #if DROPBEAR_DSS |
4
fe6bca95afa7
Makefile.in contains updated files required
Matt Johnston <matt@ucc.asn.au>
parents:
diff
changeset
|
698 if (key->type == OSSH_DSA) { |
1122
aaf576b27a10
Merge pull request #13 from gazoo74/fix-warnings
Matt Johnston <matt@ucc.asn.au>
parents:
1119
diff
changeset
|
699 buf_putstring(blobbuf, "ssh-dss", 7); |
836
d7d9f1612d51
writing out openssh ecc keys works
Matt Johnston <matt@ucc.asn.au>
parents:
807
diff
changeset
|
700 retkey->type = DROPBEAR_SIGNKEY_DSS; |
935
25692c60479e
Fix compiling with ECDSA and DSS disabled
Matt Johnston <matt@ucc.asn.au>
parents:
867
diff
changeset
|
701 } |
25692c60479e
Fix compiling with ECDSA and DSS disabled
Matt Johnston <matt@ucc.asn.au>
parents:
867
diff
changeset
|
702 #endif |
1295
750ec4ec4cbe
Convert #ifdef to #if, other build changes
Matt Johnston <matt@ucc.asn.au>
parents:
1294
diff
changeset
|
703 #if DROPBEAR_RSA |
935
25692c60479e
Fix compiling with ECDSA and DSS disabled
Matt Johnston <matt@ucc.asn.au>
parents:
867
diff
changeset
|
704 if (key->type == OSSH_RSA) { |
1122
aaf576b27a10
Merge pull request #13 from gazoo74/fix-warnings
Matt Johnston <matt@ucc.asn.au>
parents:
1119
diff
changeset
|
705 buf_putstring(blobbuf, "ssh-rsa", 7); |
836
d7d9f1612d51
writing out openssh ecc keys works
Matt Johnston <matt@ucc.asn.au>
parents:
807
diff
changeset
|
706 retkey->type = DROPBEAR_SIGNKEY_RSA; |
4
fe6bca95afa7
Makefile.in contains updated files required
Matt Johnston <matt@ucc.asn.au>
parents:
diff
changeset
|
707 } |
935
25692c60479e
Fix compiling with ECDSA and DSS disabled
Matt Johnston <matt@ucc.asn.au>
parents:
867
diff
changeset
|
708 #endif |
4
fe6bca95afa7
Makefile.in contains updated files required
Matt Johnston <matt@ucc.asn.au>
parents:
diff
changeset
|
709 |
1308 | 710 for (i = 0; i < num_integers; i++) { |
806
71e7d31f7671
hackish ECC import code from OpenSSH
Matt Johnston <matt@ucc.asn.au>
parents:
793
diff
changeset
|
711 ret = ber_read_id_len(p, key->keyblob+key->keyblob_len-p, |
71e7d31f7671
hackish ECC import code from OpenSSH
Matt Johnston <matt@ucc.asn.au>
parents:
793
diff
changeset
|
712 &id, &len, &flags); |
71e7d31f7671
hackish ECC import code from OpenSSH
Matt Johnston <matt@ucc.asn.au>
parents:
793
diff
changeset
|
713 p += ret; |
1308 | 714 if (ret < 0 || id != 2 || len < 0 || |
806
71e7d31f7671
hackish ECC import code from OpenSSH
Matt Johnston <matt@ucc.asn.au>
parents:
793
diff
changeset
|
715 key->keyblob+key->keyblob_len-p < len) { |
71e7d31f7671
hackish ECC import code from OpenSSH
Matt Johnston <matt@ucc.asn.au>
parents:
793
diff
changeset
|
716 errmsg = "ASN.1 decoding failure"; |
71e7d31f7671
hackish ECC import code from OpenSSH
Matt Johnston <matt@ucc.asn.au>
parents:
793
diff
changeset
|
717 goto error; |
71e7d31f7671
hackish ECC import code from OpenSSH
Matt Johnston <matt@ucc.asn.au>
parents:
793
diff
changeset
|
718 } |
71e7d31f7671
hackish ECC import code from OpenSSH
Matt Johnston <matt@ucc.asn.au>
parents:
793
diff
changeset
|
719 |
1308 | 720 if (i == 0) { |
806
71e7d31f7671
hackish ECC import code from OpenSSH
Matt Johnston <matt@ucc.asn.au>
parents:
793
diff
changeset
|
721 /* First integer is a version indicator */ |
991
4f65c867fc99
Fix variables may be uninitialized.
Like Ma <likemartinma@gmail.com>
parents:
935
diff
changeset
|
722 int expected = -1; |
806
71e7d31f7671
hackish ECC import code from OpenSSH
Matt Johnston <matt@ucc.asn.au>
parents:
793
diff
changeset
|
723 switch (key->type) { |
71e7d31f7671
hackish ECC import code from OpenSSH
Matt Johnston <matt@ucc.asn.au>
parents:
793
diff
changeset
|
724 case OSSH_RSA: |
71e7d31f7671
hackish ECC import code from OpenSSH
Matt Johnston <matt@ucc.asn.au>
parents:
793
diff
changeset
|
725 case OSSH_DSA: |
71e7d31f7671
hackish ECC import code from OpenSSH
Matt Johnston <matt@ucc.asn.au>
parents:
793
diff
changeset
|
726 expected = 0; |
71e7d31f7671
hackish ECC import code from OpenSSH
Matt Johnston <matt@ucc.asn.au>
parents:
793
diff
changeset
|
727 break; |
71e7d31f7671
hackish ECC import code from OpenSSH
Matt Johnston <matt@ucc.asn.au>
parents:
793
diff
changeset
|
728 case OSSH_EC: |
71e7d31f7671
hackish ECC import code from OpenSSH
Matt Johnston <matt@ucc.asn.au>
parents:
793
diff
changeset
|
729 expected = 1; |
71e7d31f7671
hackish ECC import code from OpenSSH
Matt Johnston <matt@ucc.asn.au>
parents:
793
diff
changeset
|
730 break; |
71e7d31f7671
hackish ECC import code from OpenSSH
Matt Johnston <matt@ucc.asn.au>
parents:
793
diff
changeset
|
731 } |
71e7d31f7671
hackish ECC import code from OpenSSH
Matt Johnston <matt@ucc.asn.au>
parents:
793
diff
changeset
|
732 if (len != 1 || p[0] != expected) { |
1308 | 733 errmsg = "Version number mismatch"; |
734 goto error; | |
735 } | |
736 } else if (key->type == OSSH_RSA) { | |
737 /* | |
4
fe6bca95afa7
Makefile.in contains updated files required
Matt Johnston <matt@ucc.asn.au>
parents:
diff
changeset
|
738 * OpenSSH key order is n, e, d, p, q, dmp1, dmq1, iqmp |
fe6bca95afa7
Makefile.in contains updated files required
Matt Johnston <matt@ucc.asn.au>
parents:
diff
changeset
|
739 * but we want e, n, d, p, q |
1308 | 740 */ |
741 if (i == 1) { | |
742 /* Save the details for after we deal with number 2. */ | |
1119
845922d73e9c
Turn modptr local variable into unsigned char *
Gaël PORTAY <gael.portay@gmail.com>
parents:
1094
diff
changeset
|
743 modptr = p; |
1308 | 744 modlen = len; |
4
fe6bca95afa7
Makefile.in contains updated files required
Matt Johnston <matt@ucc.asn.au>
parents:
diff
changeset
|
745 } else if (i >= 2 && i <= 5) { |
1122
aaf576b27a10
Merge pull request #13 from gazoo74/fix-warnings
Matt Johnston <matt@ucc.asn.au>
parents:
1119
diff
changeset
|
746 buf_putstring(blobbuf, (const char*)p, len); |
1308 | 747 if (i == 2) { |
1122
aaf576b27a10
Merge pull request #13 from gazoo74/fix-warnings
Matt Johnston <matt@ucc.asn.au>
parents:
1119
diff
changeset
|
748 buf_putstring(blobbuf, (const char*)modptr, modlen); |
1308 | 749 } |
750 } | |
751 } else if (key->type == OSSH_DSA) { | |
752 /* | |
4
fe6bca95afa7
Makefile.in contains updated files required
Matt Johnston <matt@ucc.asn.au>
parents:
diff
changeset
|
753 * OpenSSH key order is p, q, g, y, x, |
fe6bca95afa7
Makefile.in contains updated files required
Matt Johnston <matt@ucc.asn.au>
parents:
diff
changeset
|
754 * we want the same. |
1308 | 755 */ |
1122
aaf576b27a10
Merge pull request #13 from gazoo74/fix-warnings
Matt Johnston <matt@ucc.asn.au>
parents:
1119
diff
changeset
|
756 buf_putstring(blobbuf, (const char*)p, len); |
806
71e7d31f7671
hackish ECC import code from OpenSSH
Matt Johnston <matt@ucc.asn.au>
parents:
793
diff
changeset
|
757 } |
71e7d31f7671
hackish ECC import code from OpenSSH
Matt Johnston <matt@ucc.asn.au>
parents:
793
diff
changeset
|
758 |
1308 | 759 /* Skip past the number. */ |
806
71e7d31f7671
hackish ECC import code from OpenSSH
Matt Johnston <matt@ucc.asn.au>
parents:
793
diff
changeset
|
760 p += len; |
1308 | 761 } |
806
71e7d31f7671
hackish ECC import code from OpenSSH
Matt Johnston <matt@ucc.asn.au>
parents:
793
diff
changeset
|
762 |
1295
750ec4ec4cbe
Convert #ifdef to #if, other build changes
Matt Johnston <matt@ucc.asn.au>
parents:
1294
diff
changeset
|
763 #if DROPBEAR_ECDSA |
806
71e7d31f7671
hackish ECC import code from OpenSSH
Matt Johnston <matt@ucc.asn.au>
parents:
793
diff
changeset
|
764 if (key->type == OSSH_EC) { |
71e7d31f7671
hackish ECC import code from OpenSSH
Matt Johnston <matt@ucc.asn.au>
parents:
793
diff
changeset
|
765 unsigned char* private_key_bytes = NULL; |
71e7d31f7671
hackish ECC import code from OpenSSH
Matt Johnston <matt@ucc.asn.au>
parents:
793
diff
changeset
|
766 int private_key_len = 0; |
71e7d31f7671
hackish ECC import code from OpenSSH
Matt Johnston <matt@ucc.asn.au>
parents:
793
diff
changeset
|
767 unsigned char* public_key_bytes = NULL; |
71e7d31f7671
hackish ECC import code from OpenSSH
Matt Johnston <matt@ucc.asn.au>
parents:
793
diff
changeset
|
768 int public_key_len = 0; |
807
75509065db53
have separate ecdsa keys for each size
Matt Johnston <matt@ucc.asn.au>
parents:
806
diff
changeset
|
769 ecc_key *ecc = NULL; |
806
71e7d31f7671
hackish ECC import code from OpenSSH
Matt Johnston <matt@ucc.asn.au>
parents:
793
diff
changeset
|
770 const struct dropbear_ecc_curve *curve = NULL; |
1308 | 771 |
857 | 772 /* See SEC1 v2, Appendix C.4 */ |
773 /* OpenSSL (so OpenSSH) seems to include the optional parts. */ | |
1308 | 774 |
857 | 775 /* privateKey OCTET STRING, */ |
806
71e7d31f7671
hackish ECC import code from OpenSSH
Matt Johnston <matt@ucc.asn.au>
parents:
793
diff
changeset
|
776 ret = ber_read_id_len(p, key->keyblob+key->keyblob_len-p, |
71e7d31f7671
hackish ECC import code from OpenSSH
Matt Johnston <matt@ucc.asn.au>
parents:
793
diff
changeset
|
777 &id, &len, &flags); |
71e7d31f7671
hackish ECC import code from OpenSSH
Matt Johnston <matt@ucc.asn.au>
parents:
793
diff
changeset
|
778 p += ret; |
857 | 779 /* id==4 for octet string */ |
1395
77c0d57a4410
fix indentation
Francois Perrad <francois.perrad@gadz.org>
parents:
1316
diff
changeset
|
780 if (ret < 0 || id != 4 || len < 0 || |
806
71e7d31f7671
hackish ECC import code from OpenSSH
Matt Johnston <matt@ucc.asn.au>
parents:
793
diff
changeset
|
781 key->keyblob+key->keyblob_len-p < len) { |
71e7d31f7671
hackish ECC import code from OpenSSH
Matt Johnston <matt@ucc.asn.au>
parents:
793
diff
changeset
|
782 errmsg = "ASN.1 decoding failure"; |
71e7d31f7671
hackish ECC import code from OpenSSH
Matt Johnston <matt@ucc.asn.au>
parents:
793
diff
changeset
|
783 goto error; |
71e7d31f7671
hackish ECC import code from OpenSSH
Matt Johnston <matt@ucc.asn.au>
parents:
793
diff
changeset
|
784 } |
71e7d31f7671
hackish ECC import code from OpenSSH
Matt Johnston <matt@ucc.asn.au>
parents:
793
diff
changeset
|
785 private_key_bytes = p; |
71e7d31f7671
hackish ECC import code from OpenSSH
Matt Johnston <matt@ucc.asn.au>
parents:
793
diff
changeset
|
786 private_key_len = len; |
71e7d31f7671
hackish ECC import code from OpenSSH
Matt Johnston <matt@ucc.asn.au>
parents:
793
diff
changeset
|
787 p += len; |
1308 | 788 |
857 | 789 /* parameters [0] ECDomainParameters {{ SECGCurveNames }} OPTIONAL, */ |
806
71e7d31f7671
hackish ECC import code from OpenSSH
Matt Johnston <matt@ucc.asn.au>
parents:
793
diff
changeset
|
790 ret = ber_read_id_len(p, key->keyblob+key->keyblob_len-p, |
71e7d31f7671
hackish ECC import code from OpenSSH
Matt Johnston <matt@ucc.asn.au>
parents:
793
diff
changeset
|
791 &id, &len, &flags); |
71e7d31f7671
hackish ECC import code from OpenSSH
Matt Johnston <matt@ucc.asn.au>
parents:
793
diff
changeset
|
792 p += ret; |
857 | 793 /* id==0 */ |
1395
77c0d57a4410
fix indentation
Francois Perrad <francois.perrad@gadz.org>
parents:
1316
diff
changeset
|
794 if (ret < 0 || id != 0 || len < 0) { |
806
71e7d31f7671
hackish ECC import code from OpenSSH
Matt Johnston <matt@ucc.asn.au>
parents:
793
diff
changeset
|
795 errmsg = "ASN.1 decoding failure"; |
71e7d31f7671
hackish ECC import code from OpenSSH
Matt Johnston <matt@ucc.asn.au>
parents:
793
diff
changeset
|
796 goto error; |
71e7d31f7671
hackish ECC import code from OpenSSH
Matt Johnston <matt@ucc.asn.au>
parents:
793
diff
changeset
|
797 } |
1308 | 798 |
806
71e7d31f7671
hackish ECC import code from OpenSSH
Matt Johnston <matt@ucc.asn.au>
parents:
793
diff
changeset
|
799 ret = ber_read_id_len(p, key->keyblob+key->keyblob_len-p, |
71e7d31f7671
hackish ECC import code from OpenSSH
Matt Johnston <matt@ucc.asn.au>
parents:
793
diff
changeset
|
800 &id, &len, &flags); |
71e7d31f7671
hackish ECC import code from OpenSSH
Matt Johnston <matt@ucc.asn.au>
parents:
793
diff
changeset
|
801 p += ret; |
857 | 802 /* id==6 for object */ |
1395
77c0d57a4410
fix indentation
Francois Perrad <francois.perrad@gadz.org>
parents:
1316
diff
changeset
|
803 if (ret < 0 || id != 6 || len < 0 || |
806
71e7d31f7671
hackish ECC import code from OpenSSH
Matt Johnston <matt@ucc.asn.au>
parents:
793
diff
changeset
|
804 key->keyblob+key->keyblob_len-p < len) { |
71e7d31f7671
hackish ECC import code from OpenSSH
Matt Johnston <matt@ucc.asn.au>
parents:
793
diff
changeset
|
805 errmsg = "ASN.1 decoding failure"; |
71e7d31f7671
hackish ECC import code from OpenSSH
Matt Johnston <matt@ucc.asn.au>
parents:
793
diff
changeset
|
806 goto error; |
71e7d31f7671
hackish ECC import code from OpenSSH
Matt Johnston <matt@ucc.asn.au>
parents:
793
diff
changeset
|
807 } |
1308 | 808 |
847
f4bb964c8678
Add '-R' for delayed hostkey option
Matt Johnston <matt@ucc.asn.au>
parents:
846
diff
changeset
|
809 if (0) {} |
1295
750ec4ec4cbe
Convert #ifdef to #if, other build changes
Matt Johnston <matt@ucc.asn.au>
parents:
1294
diff
changeset
|
810 #if DROPBEAR_ECC_256 |
847
f4bb964c8678
Add '-R' for delayed hostkey option
Matt Johnston <matt@ucc.asn.au>
parents:
846
diff
changeset
|
811 else if (len == sizeof(OID_SEC256R1_BLOB) |
806
71e7d31f7671
hackish ECC import code from OpenSSH
Matt Johnston <matt@ucc.asn.au>
parents:
793
diff
changeset
|
812 && memcmp(p, OID_SEC256R1_BLOB, len) == 0) { |
71e7d31f7671
hackish ECC import code from OpenSSH
Matt Johnston <matt@ucc.asn.au>
parents:
793
diff
changeset
|
813 retkey->type = DROPBEAR_SIGNKEY_ECDSA_NISTP256; |
71e7d31f7671
hackish ECC import code from OpenSSH
Matt Johnston <matt@ucc.asn.au>
parents:
793
diff
changeset
|
814 curve = &ecc_curve_nistp256; |
847
f4bb964c8678
Add '-R' for delayed hostkey option
Matt Johnston <matt@ucc.asn.au>
parents:
846
diff
changeset
|
815 } |
1308 | 816 #endif |
1295
750ec4ec4cbe
Convert #ifdef to #if, other build changes
Matt Johnston <matt@ucc.asn.au>
parents:
1294
diff
changeset
|
817 #if DROPBEAR_ECC_384 |
847
f4bb964c8678
Add '-R' for delayed hostkey option
Matt Johnston <matt@ucc.asn.au>
parents:
846
diff
changeset
|
818 else if (len == sizeof(OID_SEC384R1_BLOB) |
806
71e7d31f7671
hackish ECC import code from OpenSSH
Matt Johnston <matt@ucc.asn.au>
parents:
793
diff
changeset
|
819 && memcmp(p, OID_SEC384R1_BLOB, len) == 0) { |
71e7d31f7671
hackish ECC import code from OpenSSH
Matt Johnston <matt@ucc.asn.au>
parents:
793
diff
changeset
|
820 retkey->type = DROPBEAR_SIGNKEY_ECDSA_NISTP384; |
71e7d31f7671
hackish ECC import code from OpenSSH
Matt Johnston <matt@ucc.asn.au>
parents:
793
diff
changeset
|
821 curve = &ecc_curve_nistp384; |
847
f4bb964c8678
Add '-R' for delayed hostkey option
Matt Johnston <matt@ucc.asn.au>
parents:
846
diff
changeset
|
822 } |
1308 | 823 #endif |
1295
750ec4ec4cbe
Convert #ifdef to #if, other build changes
Matt Johnston <matt@ucc.asn.au>
parents:
1294
diff
changeset
|
824 #if DROPBEAR_ECC_521 |
847
f4bb964c8678
Add '-R' for delayed hostkey option
Matt Johnston <matt@ucc.asn.au>
parents:
846
diff
changeset
|
825 else if (len == sizeof(OID_SEC521R1_BLOB) |
806
71e7d31f7671
hackish ECC import code from OpenSSH
Matt Johnston <matt@ucc.asn.au>
parents:
793
diff
changeset
|
826 && memcmp(p, OID_SEC521R1_BLOB, len) == 0) { |
71e7d31f7671
hackish ECC import code from OpenSSH
Matt Johnston <matt@ucc.asn.au>
parents:
793
diff
changeset
|
827 retkey->type = DROPBEAR_SIGNKEY_ECDSA_NISTP521; |
71e7d31f7671
hackish ECC import code from OpenSSH
Matt Johnston <matt@ucc.asn.au>
parents:
793
diff
changeset
|
828 curve = &ecc_curve_nistp521; |
847
f4bb964c8678
Add '-R' for delayed hostkey option
Matt Johnston <matt@ucc.asn.au>
parents:
846
diff
changeset
|
829 } |
1308 | 830 #endif |
847
f4bb964c8678
Add '-R' for delayed hostkey option
Matt Johnston <matt@ucc.asn.au>
parents:
846
diff
changeset
|
831 else { |
806
71e7d31f7671
hackish ECC import code from OpenSSH
Matt Johnston <matt@ucc.asn.au>
parents:
793
diff
changeset
|
832 errmsg = "Unknown ECC key type"; |
71e7d31f7671
hackish ECC import code from OpenSSH
Matt Johnston <matt@ucc.asn.au>
parents:
793
diff
changeset
|
833 goto error; |
71e7d31f7671
hackish ECC import code from OpenSSH
Matt Johnston <matt@ucc.asn.au>
parents:
793
diff
changeset
|
834 } |
71e7d31f7671
hackish ECC import code from OpenSSH
Matt Johnston <matt@ucc.asn.au>
parents:
793
diff
changeset
|
835 p += len; |
1308 | 836 |
857 | 837 /* publicKey [1] BIT STRING OPTIONAL */ |
806
71e7d31f7671
hackish ECC import code from OpenSSH
Matt Johnston <matt@ucc.asn.au>
parents:
793
diff
changeset
|
838 ret = ber_read_id_len(p, key->keyblob+key->keyblob_len-p, |
71e7d31f7671
hackish ECC import code from OpenSSH
Matt Johnston <matt@ucc.asn.au>
parents:
793
diff
changeset
|
839 &id, &len, &flags); |
71e7d31f7671
hackish ECC import code from OpenSSH
Matt Johnston <matt@ucc.asn.au>
parents:
793
diff
changeset
|
840 p += ret; |
857 | 841 /* id==1 */ |
1395
77c0d57a4410
fix indentation
Francois Perrad <francois.perrad@gadz.org>
parents:
1316
diff
changeset
|
842 if (ret < 0 || id != 1 || len < 0) { |
806
71e7d31f7671
hackish ECC import code from OpenSSH
Matt Johnston <matt@ucc.asn.au>
parents:
793
diff
changeset
|
843 errmsg = "ASN.1 decoding failure"; |
71e7d31f7671
hackish ECC import code from OpenSSH
Matt Johnston <matt@ucc.asn.au>
parents:
793
diff
changeset
|
844 goto error; |
71e7d31f7671
hackish ECC import code from OpenSSH
Matt Johnston <matt@ucc.asn.au>
parents:
793
diff
changeset
|
845 } |
1308 | 846 |
806
71e7d31f7671
hackish ECC import code from OpenSSH
Matt Johnston <matt@ucc.asn.au>
parents:
793
diff
changeset
|
847 ret = ber_read_id_len(p, key->keyblob+key->keyblob_len-p, |
71e7d31f7671
hackish ECC import code from OpenSSH
Matt Johnston <matt@ucc.asn.au>
parents:
793
diff
changeset
|
848 &id, &len, &flags); |
71e7d31f7671
hackish ECC import code from OpenSSH
Matt Johnston <matt@ucc.asn.au>
parents:
793
diff
changeset
|
849 p += ret; |
857 | 850 /* id==3 for bit string */ |
1395
77c0d57a4410
fix indentation
Francois Perrad <francois.perrad@gadz.org>
parents:
1316
diff
changeset
|
851 if (ret < 0 || id != 3 || len < 0 || |
806
71e7d31f7671
hackish ECC import code from OpenSSH
Matt Johnston <matt@ucc.asn.au>
parents:
793
diff
changeset
|
852 key->keyblob+key->keyblob_len-p < len) { |
71e7d31f7671
hackish ECC import code from OpenSSH
Matt Johnston <matt@ucc.asn.au>
parents:
793
diff
changeset
|
853 errmsg = "ASN.1 decoding failure"; |
71e7d31f7671
hackish ECC import code from OpenSSH
Matt Johnston <matt@ucc.asn.au>
parents:
793
diff
changeset
|
854 goto error; |
71e7d31f7671
hackish ECC import code from OpenSSH
Matt Johnston <matt@ucc.asn.au>
parents:
793
diff
changeset
|
855 } |
71e7d31f7671
hackish ECC import code from OpenSSH
Matt Johnston <matt@ucc.asn.au>
parents:
793
diff
changeset
|
856 public_key_bytes = p+1; |
71e7d31f7671
hackish ECC import code from OpenSSH
Matt Johnston <matt@ucc.asn.au>
parents:
793
diff
changeset
|
857 public_key_len = len-1; |
71e7d31f7671
hackish ECC import code from OpenSSH
Matt Johnston <matt@ucc.asn.au>
parents:
793
diff
changeset
|
858 p += len; |
1308 | 859 |
806
71e7d31f7671
hackish ECC import code from OpenSSH
Matt Johnston <matt@ucc.asn.au>
parents:
793
diff
changeset
|
860 buf_putbytes(blobbuf, public_key_bytes, public_key_len); |
71e7d31f7671
hackish ECC import code from OpenSSH
Matt Johnston <matt@ucc.asn.au>
parents:
793
diff
changeset
|
861 ecc = buf_get_ecc_raw_pubkey(blobbuf, curve); |
71e7d31f7671
hackish ECC import code from OpenSSH
Matt Johnston <matt@ucc.asn.au>
parents:
793
diff
changeset
|
862 if (!ecc) { |
71e7d31f7671
hackish ECC import code from OpenSSH
Matt Johnston <matt@ucc.asn.au>
parents:
793
diff
changeset
|
863 errmsg = "Error parsing ECC key"; |
71e7d31f7671
hackish ECC import code from OpenSSH
Matt Johnston <matt@ucc.asn.au>
parents:
793
diff
changeset
|
864 goto error; |
71e7d31f7671
hackish ECC import code from OpenSSH
Matt Johnston <matt@ucc.asn.au>
parents:
793
diff
changeset
|
865 } |
71e7d31f7671
hackish ECC import code from OpenSSH
Matt Johnston <matt@ucc.asn.au>
parents:
793
diff
changeset
|
866 m_mp_alloc_init_multi((mp_int**)&ecc->k, NULL); |
71e7d31f7671
hackish ECC import code from OpenSSH
Matt Johnston <matt@ucc.asn.au>
parents:
793
diff
changeset
|
867 if (mp_read_unsigned_bin(ecc->k, private_key_bytes, private_key_len) |
71e7d31f7671
hackish ECC import code from OpenSSH
Matt Johnston <matt@ucc.asn.au>
parents:
793
diff
changeset
|
868 != MP_OKAY) { |
71e7d31f7671
hackish ECC import code from OpenSSH
Matt Johnston <matt@ucc.asn.au>
parents:
793
diff
changeset
|
869 errmsg = "Error parsing ECC key"; |
71e7d31f7671
hackish ECC import code from OpenSSH
Matt Johnston <matt@ucc.asn.au>
parents:
793
diff
changeset
|
870 goto error; |
71e7d31f7671
hackish ECC import code from OpenSSH
Matt Johnston <matt@ucc.asn.au>
parents:
793
diff
changeset
|
871 } |
1308 | 872 |
841
d4ce5269a439
Fix specifying a keysize for key generation, fix key name arguments
Matt Johnston <matt@ucc.asn.au>
parents:
807
diff
changeset
|
873 *signkey_key_ptr(retkey, retkey->type) = ecc; |
806
71e7d31f7671
hackish ECC import code from OpenSSH
Matt Johnston <matt@ucc.asn.au>
parents:
793
diff
changeset
|
874 } |
1308 | 875 #endif /* DROPBEAR_ECDSA */ |
876 | |
877 /* | |
878 * Now put together the actual key. Simplest way to do this is | |
879 * to assemble our own key blobs and feed them to the createkey | |
880 * functions; this is a bit faffy but it does mean we get all | |
881 * the sanity checks for free. | |
882 */ | |
806
71e7d31f7671
hackish ECC import code from OpenSSH
Matt Johnston <matt@ucc.asn.au>
parents:
793
diff
changeset
|
883 if (key->type == OSSH_RSA || key->type == OSSH_DSA) { |
71e7d31f7671
hackish ECC import code from OpenSSH
Matt Johnston <matt@ucc.asn.au>
parents:
793
diff
changeset
|
884 buf_setpos(blobbuf, 0); |
71e7d31f7671
hackish ECC import code from OpenSSH
Matt Johnston <matt@ucc.asn.au>
parents:
793
diff
changeset
|
885 type = DROPBEAR_SIGNKEY_ANY; |
71e7d31f7671
hackish ECC import code from OpenSSH
Matt Johnston <matt@ucc.asn.au>
parents:
793
diff
changeset
|
886 if (buf_get_priv_key(blobbuf, retkey, &type) |
71e7d31f7671
hackish ECC import code from OpenSSH
Matt Johnston <matt@ucc.asn.au>
parents:
793
diff
changeset
|
887 != DROPBEAR_SUCCESS) { |
71e7d31f7671
hackish ECC import code from OpenSSH
Matt Johnston <matt@ucc.asn.au>
parents:
793
diff
changeset
|
888 errmsg = "unable to create key structure"; |
71e7d31f7671
hackish ECC import code from OpenSSH
Matt Johnston <matt@ucc.asn.au>
parents:
793
diff
changeset
|
889 sign_key_free(retkey); |
71e7d31f7671
hackish ECC import code from OpenSSH
Matt Johnston <matt@ucc.asn.au>
parents:
793
diff
changeset
|
890 retkey = NULL; |
71e7d31f7671
hackish ECC import code from OpenSSH
Matt Johnston <matt@ucc.asn.au>
parents:
793
diff
changeset
|
891 goto error; |
71e7d31f7671
hackish ECC import code from OpenSSH
Matt Johnston <matt@ucc.asn.au>
parents:
793
diff
changeset
|
892 } |
1308 | 893 } |
806
71e7d31f7671
hackish ECC import code from OpenSSH
Matt Johnston <matt@ucc.asn.au>
parents:
793
diff
changeset
|
894 |
4
fe6bca95afa7
Makefile.in contains updated files required
Matt Johnston <matt@ucc.asn.au>
parents:
diff
changeset
|
895 errmsg = NULL; /* no error */ |
1308 | 896 retval = retkey; |
806
71e7d31f7671
hackish ECC import code from OpenSSH
Matt Johnston <matt@ucc.asn.au>
parents:
793
diff
changeset
|
897 |
1308 | 898 error: |
4
fe6bca95afa7
Makefile.in contains updated files required
Matt Johnston <matt@ucc.asn.au>
parents:
diff
changeset
|
899 if (blobbuf) { |
fe6bca95afa7
Makefile.in contains updated files required
Matt Johnston <matt@ucc.asn.au>
parents:
diff
changeset
|
900 buf_burn(blobbuf); |
fe6bca95afa7
Makefile.in contains updated files required
Matt Johnston <matt@ucc.asn.au>
parents:
diff
changeset
|
901 buf_free(blobbuf); |
1308 | 902 } |
4
fe6bca95afa7
Makefile.in contains updated files required
Matt Johnston <matt@ucc.asn.au>
parents:
diff
changeset
|
903 m_burn(key->keyblob, key->keyblob_size); |
fe6bca95afa7
Makefile.in contains updated files required
Matt Johnston <matt@ucc.asn.au>
parents:
diff
changeset
|
904 m_free(key->keyblob); |
1002
97d1e54941fd
When clearing the memory of 'key' in function openssh_read(), only the size
Christian Engelmayer <cengelma@gmx.at>
parents:
991
diff
changeset
|
905 m_burn(key, sizeof(*key)); |
4
fe6bca95afa7
Makefile.in contains updated files required
Matt Johnston <matt@ucc.asn.au>
parents:
diff
changeset
|
906 m_free(key); |
fe6bca95afa7
Makefile.in contains updated files required
Matt Johnston <matt@ucc.asn.au>
parents:
diff
changeset
|
907 if (errmsg) { |
fe6bca95afa7
Makefile.in contains updated files required
Matt Johnston <matt@ucc.asn.au>
parents:
diff
changeset
|
908 fprintf(stderr, "Error: %s\n", errmsg); |
fe6bca95afa7
Makefile.in contains updated files required
Matt Johnston <matt@ucc.asn.au>
parents:
diff
changeset
|
909 } |
1308 | 910 return retval; |
4
fe6bca95afa7
Makefile.in contains updated files required
Matt Johnston <matt@ucc.asn.au>
parents:
diff
changeset
|
911 } |
fe6bca95afa7
Makefile.in contains updated files required
Matt Johnston <matt@ucc.asn.au>
parents:
diff
changeset
|
912 |
fe6bca95afa7
Makefile.in contains updated files required
Matt Johnston <matt@ucc.asn.au>
parents:
diff
changeset
|
913 static int openssh_write(const char *filename, sign_key *key, |
1459
06d52bcb8094
Pointer parameter could be declared as pointing to const
Francois Perrad <francois.perrad@gadz.org>
parents:
1395
diff
changeset
|
914 const char *passphrase) |
4
fe6bca95afa7
Makefile.in contains updated files required
Matt Johnston <matt@ucc.asn.au>
parents:
diff
changeset
|
915 { |
fe6bca95afa7
Makefile.in contains updated files required
Matt Johnston <matt@ucc.asn.au>
parents:
diff
changeset
|
916 buffer * keyblob = NULL; |
fe6bca95afa7
Makefile.in contains updated files required
Matt Johnston <matt@ucc.asn.au>
parents:
diff
changeset
|
917 buffer * extrablob = NULL; /* used for calculated values to write */ |
fe6bca95afa7
Makefile.in contains updated files required
Matt Johnston <matt@ucc.asn.au>
parents:
diff
changeset
|
918 unsigned char *outblob = NULL; |
fe6bca95afa7
Makefile.in contains updated files required
Matt Johnston <matt@ucc.asn.au>
parents:
diff
changeset
|
919 int outlen = -9999; |
1308 | 920 struct mpint_pos numbers[9]; |
991
4f65c867fc99
Fix variables may be uninitialized.
Like Ma <likemartinma@gmail.com>
parents:
935
diff
changeset
|
921 int nnumbers = -1, pos = 0, len = 0, seqlen, i; |
4
fe6bca95afa7
Makefile.in contains updated files required
Matt Johnston <matt@ucc.asn.au>
parents:
diff
changeset
|
922 char *header = NULL, *footer = NULL; |
1308 | 923 char zero[1]; |
924 int ret = 0; | |
925 FILE *fp; | |
4
fe6bca95afa7
Makefile.in contains updated files required
Matt Johnston <matt@ucc.asn.au>
parents:
diff
changeset
|
926 |
1295
750ec4ec4cbe
Convert #ifdef to #if, other build changes
Matt Johnston <matt@ucc.asn.au>
parents:
1294
diff
changeset
|
927 #if DROPBEAR_RSA |
4
fe6bca95afa7
Makefile.in contains updated files required
Matt Johnston <matt@ucc.asn.au>
parents:
diff
changeset
|
928 mp_int dmp1, dmq1, iqmp, tmpval; /* for rsa */ |
fe6bca95afa7
Makefile.in contains updated files required
Matt Johnston <matt@ucc.asn.au>
parents:
diff
changeset
|
929 #endif |
fe6bca95afa7
Makefile.in contains updated files required
Matt Johnston <matt@ucc.asn.au>
parents:
diff
changeset
|
930 |
935
25692c60479e
Fix compiling with ECDSA and DSS disabled
Matt Johnston <matt@ucc.asn.au>
parents:
867
diff
changeset
|
931 if ( |
1295
750ec4ec4cbe
Convert #ifdef to #if, other build changes
Matt Johnston <matt@ucc.asn.au>
parents:
1294
diff
changeset
|
932 #if DROPBEAR_RSA |
935
25692c60479e
Fix compiling with ECDSA and DSS disabled
Matt Johnston <matt@ucc.asn.au>
parents:
867
diff
changeset
|
933 key->type == DROPBEAR_SIGNKEY_RSA || |
25692c60479e
Fix compiling with ECDSA and DSS disabled
Matt Johnston <matt@ucc.asn.au>
parents:
867
diff
changeset
|
934 #endif |
1295
750ec4ec4cbe
Convert #ifdef to #if, other build changes
Matt Johnston <matt@ucc.asn.au>
parents:
1294
diff
changeset
|
935 #if DROPBEAR_DSS |
935
25692c60479e
Fix compiling with ECDSA and DSS disabled
Matt Johnston <matt@ucc.asn.au>
parents:
867
diff
changeset
|
936 key->type == DROPBEAR_SIGNKEY_DSS || |
25692c60479e
Fix compiling with ECDSA and DSS disabled
Matt Johnston <matt@ucc.asn.au>
parents:
867
diff
changeset
|
937 #endif |
25692c60479e
Fix compiling with ECDSA and DSS disabled
Matt Johnston <matt@ucc.asn.au>
parents:
867
diff
changeset
|
938 0) |
836
d7d9f1612d51
writing out openssh ecc keys works
Matt Johnston <matt@ucc.asn.au>
parents:
807
diff
changeset
|
939 { |
d7d9f1612d51
writing out openssh ecc keys works
Matt Johnston <matt@ucc.asn.au>
parents:
807
diff
changeset
|
940 /* |
d7d9f1612d51
writing out openssh ecc keys works
Matt Johnston <matt@ucc.asn.au>
parents:
807
diff
changeset
|
941 * Fetch the key blobs. |
d7d9f1612d51
writing out openssh ecc keys works
Matt Johnston <matt@ucc.asn.au>
parents:
807
diff
changeset
|
942 */ |
d7d9f1612d51
writing out openssh ecc keys works
Matt Johnston <matt@ucc.asn.au>
parents:
807
diff
changeset
|
943 keyblob = buf_new(3000); |
d7d9f1612d51
writing out openssh ecc keys works
Matt Johnston <matt@ucc.asn.au>
parents:
807
diff
changeset
|
944 buf_put_priv_key(keyblob, key, key->type); |
d7d9f1612d51
writing out openssh ecc keys works
Matt Johnston <matt@ucc.asn.au>
parents:
807
diff
changeset
|
945 |
d7d9f1612d51
writing out openssh ecc keys works
Matt Johnston <matt@ucc.asn.au>
parents:
807
diff
changeset
|
946 buf_setpos(keyblob, 0); |
d7d9f1612d51
writing out openssh ecc keys works
Matt Johnston <matt@ucc.asn.au>
parents:
807
diff
changeset
|
947 /* skip the "ssh-rsa" or "ssh-dss" header */ |
d7d9f1612d51
writing out openssh ecc keys works
Matt Johnston <matt@ucc.asn.au>
parents:
807
diff
changeset
|
948 buf_incrpos(keyblob, buf_getint(keyblob)); |
d7d9f1612d51
writing out openssh ecc keys works
Matt Johnston <matt@ucc.asn.au>
parents:
807
diff
changeset
|
949 |
d7d9f1612d51
writing out openssh ecc keys works
Matt Johnston <matt@ucc.asn.au>
parents:
807
diff
changeset
|
950 /* |
d7d9f1612d51
writing out openssh ecc keys works
Matt Johnston <matt@ucc.asn.au>
parents:
807
diff
changeset
|
951 * Find the sequence of integers to be encoded into the OpenSSH |
d7d9f1612d51
writing out openssh ecc keys works
Matt Johnston <matt@ucc.asn.au>
parents:
807
diff
changeset
|
952 * key blob, and also decide on the header line. |
d7d9f1612d51
writing out openssh ecc keys works
Matt Johnston <matt@ucc.asn.au>
parents:
807
diff
changeset
|
953 */ |
d7d9f1612d51
writing out openssh ecc keys works
Matt Johnston <matt@ucc.asn.au>
parents:
807
diff
changeset
|
954 numbers[0].start = zero; numbers[0].bytes = 1; zero[0] = '\0'; |
d7d9f1612d51
writing out openssh ecc keys works
Matt Johnston <matt@ucc.asn.au>
parents:
807
diff
changeset
|
955 |
1499
2d450c1056e3
options: Complete the transition to numeric toggles (`#if')
Michael Witten <mfwitten@gmail.com>
parents:
1459
diff
changeset
|
956 #if DROPBEAR_RSA |
836
d7d9f1612d51
writing out openssh ecc keys works
Matt Johnston <matt@ucc.asn.au>
parents:
807
diff
changeset
|
957 if (key->type == DROPBEAR_SIGNKEY_RSA) { |
d7d9f1612d51
writing out openssh ecc keys works
Matt Johnston <matt@ucc.asn.au>
parents:
807
diff
changeset
|
958 |
d7d9f1612d51
writing out openssh ecc keys works
Matt Johnston <matt@ucc.asn.au>
parents:
807
diff
changeset
|
959 if (key->rsakey->p == NULL || key->rsakey->q == NULL) { |
d7d9f1612d51
writing out openssh ecc keys works
Matt Johnston <matt@ucc.asn.au>
parents:
807
diff
changeset
|
960 fprintf(stderr, "Pre-0.33 Dropbear keys cannot be converted to OpenSSH keys.\n"); |
d7d9f1612d51
writing out openssh ecc keys works
Matt Johnston <matt@ucc.asn.au>
parents:
807
diff
changeset
|
961 goto error; |
d7d9f1612d51
writing out openssh ecc keys works
Matt Johnston <matt@ucc.asn.au>
parents:
807
diff
changeset
|
962 } |
1306
34e6127ef02e
merge fixes from PuTTY import.c
Matt Johnston <matt@ucc.asn.au>
parents:
1250
diff
changeset
|
963 |
836
d7d9f1612d51
writing out openssh ecc keys works
Matt Johnston <matt@ucc.asn.au>
parents:
807
diff
changeset
|
964 /* e */ |
d7d9f1612d51
writing out openssh ecc keys works
Matt Johnston <matt@ucc.asn.au>
parents:
807
diff
changeset
|
965 numbers[2].bytes = buf_getint(keyblob); |
d7d9f1612d51
writing out openssh ecc keys works
Matt Johnston <matt@ucc.asn.au>
parents:
807
diff
changeset
|
966 numbers[2].start = buf_getptr(keyblob, numbers[2].bytes); |
d7d9f1612d51
writing out openssh ecc keys works
Matt Johnston <matt@ucc.asn.au>
parents:
807
diff
changeset
|
967 buf_incrpos(keyblob, numbers[2].bytes); |
d7d9f1612d51
writing out openssh ecc keys works
Matt Johnston <matt@ucc.asn.au>
parents:
807
diff
changeset
|
968 |
d7d9f1612d51
writing out openssh ecc keys works
Matt Johnston <matt@ucc.asn.au>
parents:
807
diff
changeset
|
969 /* n */ |
d7d9f1612d51
writing out openssh ecc keys works
Matt Johnston <matt@ucc.asn.au>
parents:
807
diff
changeset
|
970 numbers[1].bytes = buf_getint(keyblob); |
d7d9f1612d51
writing out openssh ecc keys works
Matt Johnston <matt@ucc.asn.au>
parents:
807
diff
changeset
|
971 numbers[1].start = buf_getptr(keyblob, numbers[1].bytes); |
d7d9f1612d51
writing out openssh ecc keys works
Matt Johnston <matt@ucc.asn.au>
parents:
807
diff
changeset
|
972 buf_incrpos(keyblob, numbers[1].bytes); |
d7d9f1612d51
writing out openssh ecc keys works
Matt Johnston <matt@ucc.asn.au>
parents:
807
diff
changeset
|
973 |
d7d9f1612d51
writing out openssh ecc keys works
Matt Johnston <matt@ucc.asn.au>
parents:
807
diff
changeset
|
974 /* d */ |
d7d9f1612d51
writing out openssh ecc keys works
Matt Johnston <matt@ucc.asn.au>
parents:
807
diff
changeset
|
975 numbers[3].bytes = buf_getint(keyblob); |
d7d9f1612d51
writing out openssh ecc keys works
Matt Johnston <matt@ucc.asn.au>
parents:
807
diff
changeset
|
976 numbers[3].start = buf_getptr(keyblob, numbers[3].bytes); |
d7d9f1612d51
writing out openssh ecc keys works
Matt Johnston <matt@ucc.asn.au>
parents:
807
diff
changeset
|
977 buf_incrpos(keyblob, numbers[3].bytes); |
d7d9f1612d51
writing out openssh ecc keys works
Matt Johnston <matt@ucc.asn.au>
parents:
807
diff
changeset
|
978 |
d7d9f1612d51
writing out openssh ecc keys works
Matt Johnston <matt@ucc.asn.au>
parents:
807
diff
changeset
|
979 /* p */ |
d7d9f1612d51
writing out openssh ecc keys works
Matt Johnston <matt@ucc.asn.au>
parents:
807
diff
changeset
|
980 numbers[4].bytes = buf_getint(keyblob); |
d7d9f1612d51
writing out openssh ecc keys works
Matt Johnston <matt@ucc.asn.au>
parents:
807
diff
changeset
|
981 numbers[4].start = buf_getptr(keyblob, numbers[4].bytes); |
d7d9f1612d51
writing out openssh ecc keys works
Matt Johnston <matt@ucc.asn.au>
parents:
807
diff
changeset
|
982 buf_incrpos(keyblob, numbers[4].bytes); |
d7d9f1612d51
writing out openssh ecc keys works
Matt Johnston <matt@ucc.asn.au>
parents:
807
diff
changeset
|
983 |
d7d9f1612d51
writing out openssh ecc keys works
Matt Johnston <matt@ucc.asn.au>
parents:
807
diff
changeset
|
984 /* q */ |
d7d9f1612d51
writing out openssh ecc keys works
Matt Johnston <matt@ucc.asn.au>
parents:
807
diff
changeset
|
985 numbers[5].bytes = buf_getint(keyblob); |
d7d9f1612d51
writing out openssh ecc keys works
Matt Johnston <matt@ucc.asn.au>
parents:
807
diff
changeset
|
986 numbers[5].start = buf_getptr(keyblob, numbers[5].bytes); |
d7d9f1612d51
writing out openssh ecc keys works
Matt Johnston <matt@ucc.asn.au>
parents:
807
diff
changeset
|
987 buf_incrpos(keyblob, numbers[5].bytes); |
1306
34e6127ef02e
merge fixes from PuTTY import.c
Matt Johnston <matt@ucc.asn.au>
parents:
1250
diff
changeset
|
988 |
836
d7d9f1612d51
writing out openssh ecc keys works
Matt Johnston <matt@ucc.asn.au>
parents:
807
diff
changeset
|
989 /* now calculate some extra parameters: */ |
d7d9f1612d51
writing out openssh ecc keys works
Matt Johnston <matt@ucc.asn.au>
parents:
807
diff
changeset
|
990 m_mp_init(&tmpval); |
d7d9f1612d51
writing out openssh ecc keys works
Matt Johnston <matt@ucc.asn.au>
parents:
807
diff
changeset
|
991 m_mp_init(&dmp1); |
d7d9f1612d51
writing out openssh ecc keys works
Matt Johnston <matt@ucc.asn.au>
parents:
807
diff
changeset
|
992 m_mp_init(&dmq1); |
d7d9f1612d51
writing out openssh ecc keys works
Matt Johnston <matt@ucc.asn.au>
parents:
807
diff
changeset
|
993 m_mp_init(&iqmp); |
4
fe6bca95afa7
Makefile.in contains updated files required
Matt Johnston <matt@ucc.asn.au>
parents:
diff
changeset
|
994 |
836
d7d9f1612d51
writing out openssh ecc keys works
Matt Johnston <matt@ucc.asn.au>
parents:
807
diff
changeset
|
995 /* dmp1 = d mod (p-1) */ |
d7d9f1612d51
writing out openssh ecc keys works
Matt Johnston <matt@ucc.asn.au>
parents:
807
diff
changeset
|
996 if (mp_sub_d(key->rsakey->p, 1, &tmpval) != MP_OKAY) { |
d7d9f1612d51
writing out openssh ecc keys works
Matt Johnston <matt@ucc.asn.au>
parents:
807
diff
changeset
|
997 fprintf(stderr, "Bignum error for p-1\n"); |
d7d9f1612d51
writing out openssh ecc keys works
Matt Johnston <matt@ucc.asn.au>
parents:
807
diff
changeset
|
998 goto error; |
d7d9f1612d51
writing out openssh ecc keys works
Matt Johnston <matt@ucc.asn.au>
parents:
807
diff
changeset
|
999 } |
d7d9f1612d51
writing out openssh ecc keys works
Matt Johnston <matt@ucc.asn.au>
parents:
807
diff
changeset
|
1000 if (mp_mod(key->rsakey->d, &tmpval, &dmp1) != MP_OKAY) { |
d7d9f1612d51
writing out openssh ecc keys works
Matt Johnston <matt@ucc.asn.au>
parents:
807
diff
changeset
|
1001 fprintf(stderr, "Bignum error for dmp1\n"); |
d7d9f1612d51
writing out openssh ecc keys works
Matt Johnston <matt@ucc.asn.au>
parents:
807
diff
changeset
|
1002 goto error; |
d7d9f1612d51
writing out openssh ecc keys works
Matt Johnston <matt@ucc.asn.au>
parents:
807
diff
changeset
|
1003 } |
d7d9f1612d51
writing out openssh ecc keys works
Matt Johnston <matt@ucc.asn.au>
parents:
807
diff
changeset
|
1004 |
d7d9f1612d51
writing out openssh ecc keys works
Matt Johnston <matt@ucc.asn.au>
parents:
807
diff
changeset
|
1005 /* dmq1 = d mod (q-1) */ |
d7d9f1612d51
writing out openssh ecc keys works
Matt Johnston <matt@ucc.asn.au>
parents:
807
diff
changeset
|
1006 if (mp_sub_d(key->rsakey->q, 1, &tmpval) != MP_OKAY) { |
d7d9f1612d51
writing out openssh ecc keys works
Matt Johnston <matt@ucc.asn.au>
parents:
807
diff
changeset
|
1007 fprintf(stderr, "Bignum error for q-1\n"); |
d7d9f1612d51
writing out openssh ecc keys works
Matt Johnston <matt@ucc.asn.au>
parents:
807
diff
changeset
|
1008 goto error; |
d7d9f1612d51
writing out openssh ecc keys works
Matt Johnston <matt@ucc.asn.au>
parents:
807
diff
changeset
|
1009 } |
d7d9f1612d51
writing out openssh ecc keys works
Matt Johnston <matt@ucc.asn.au>
parents:
807
diff
changeset
|
1010 if (mp_mod(key->rsakey->d, &tmpval, &dmq1) != MP_OKAY) { |
d7d9f1612d51
writing out openssh ecc keys works
Matt Johnston <matt@ucc.asn.au>
parents:
807
diff
changeset
|
1011 fprintf(stderr, "Bignum error for dmq1\n"); |
d7d9f1612d51
writing out openssh ecc keys works
Matt Johnston <matt@ucc.asn.au>
parents:
807
diff
changeset
|
1012 goto error; |
d7d9f1612d51
writing out openssh ecc keys works
Matt Johnston <matt@ucc.asn.au>
parents:
807
diff
changeset
|
1013 } |
d7d9f1612d51
writing out openssh ecc keys works
Matt Johnston <matt@ucc.asn.au>
parents:
807
diff
changeset
|
1014 |
d7d9f1612d51
writing out openssh ecc keys works
Matt Johnston <matt@ucc.asn.au>
parents:
807
diff
changeset
|
1015 /* iqmp = (q^-1) mod p */ |
d7d9f1612d51
writing out openssh ecc keys works
Matt Johnston <matt@ucc.asn.au>
parents:
807
diff
changeset
|
1016 if (mp_invmod(key->rsakey->q, key->rsakey->p, &iqmp) != MP_OKAY) { |
d7d9f1612d51
writing out openssh ecc keys works
Matt Johnston <matt@ucc.asn.au>
parents:
807
diff
changeset
|
1017 fprintf(stderr, "Bignum error for iqmp\n"); |
d7d9f1612d51
writing out openssh ecc keys works
Matt Johnston <matt@ucc.asn.au>
parents:
807
diff
changeset
|
1018 goto error; |
d7d9f1612d51
writing out openssh ecc keys works
Matt Johnston <matt@ucc.asn.au>
parents:
807
diff
changeset
|
1019 } |
4
fe6bca95afa7
Makefile.in contains updated files required
Matt Johnston <matt@ucc.asn.au>
parents:
diff
changeset
|
1020 |
836
d7d9f1612d51
writing out openssh ecc keys works
Matt Johnston <matt@ucc.asn.au>
parents:
807
diff
changeset
|
1021 extrablob = buf_new(2000); |
d7d9f1612d51
writing out openssh ecc keys works
Matt Johnston <matt@ucc.asn.au>
parents:
807
diff
changeset
|
1022 buf_putmpint(extrablob, &dmp1); |
d7d9f1612d51
writing out openssh ecc keys works
Matt Johnston <matt@ucc.asn.au>
parents:
807
diff
changeset
|
1023 buf_putmpint(extrablob, &dmq1); |
d7d9f1612d51
writing out openssh ecc keys works
Matt Johnston <matt@ucc.asn.au>
parents:
807
diff
changeset
|
1024 buf_putmpint(extrablob, &iqmp); |
d7d9f1612d51
writing out openssh ecc keys works
Matt Johnston <matt@ucc.asn.au>
parents:
807
diff
changeset
|
1025 buf_setpos(extrablob, 0); |
d7d9f1612d51
writing out openssh ecc keys works
Matt Johnston <matt@ucc.asn.au>
parents:
807
diff
changeset
|
1026 mp_clear(&dmp1); |
d7d9f1612d51
writing out openssh ecc keys works
Matt Johnston <matt@ucc.asn.au>
parents:
807
diff
changeset
|
1027 mp_clear(&dmq1); |
d7d9f1612d51
writing out openssh ecc keys works
Matt Johnston <matt@ucc.asn.au>
parents:
807
diff
changeset
|
1028 mp_clear(&iqmp); |
d7d9f1612d51
writing out openssh ecc keys works
Matt Johnston <matt@ucc.asn.au>
parents:
807
diff
changeset
|
1029 mp_clear(&tmpval); |
d7d9f1612d51
writing out openssh ecc keys works
Matt Johnston <matt@ucc.asn.au>
parents:
807
diff
changeset
|
1030 |
d7d9f1612d51
writing out openssh ecc keys works
Matt Johnston <matt@ucc.asn.au>
parents:
807
diff
changeset
|
1031 /* dmp1 */ |
d7d9f1612d51
writing out openssh ecc keys works
Matt Johnston <matt@ucc.asn.au>
parents:
807
diff
changeset
|
1032 numbers[6].bytes = buf_getint(extrablob); |
d7d9f1612d51
writing out openssh ecc keys works
Matt Johnston <matt@ucc.asn.au>
parents:
807
diff
changeset
|
1033 numbers[6].start = buf_getptr(extrablob, numbers[6].bytes); |
d7d9f1612d51
writing out openssh ecc keys works
Matt Johnston <matt@ucc.asn.au>
parents:
807
diff
changeset
|
1034 buf_incrpos(extrablob, numbers[6].bytes); |
d7d9f1612d51
writing out openssh ecc keys works
Matt Johnston <matt@ucc.asn.au>
parents:
807
diff
changeset
|
1035 |
d7d9f1612d51
writing out openssh ecc keys works
Matt Johnston <matt@ucc.asn.au>
parents:
807
diff
changeset
|
1036 /* dmq1 */ |
d7d9f1612d51
writing out openssh ecc keys works
Matt Johnston <matt@ucc.asn.au>
parents:
807
diff
changeset
|
1037 numbers[7].bytes = buf_getint(extrablob); |
d7d9f1612d51
writing out openssh ecc keys works
Matt Johnston <matt@ucc.asn.au>
parents:
807
diff
changeset
|
1038 numbers[7].start = buf_getptr(extrablob, numbers[7].bytes); |
d7d9f1612d51
writing out openssh ecc keys works
Matt Johnston <matt@ucc.asn.au>
parents:
807
diff
changeset
|
1039 buf_incrpos(extrablob, numbers[7].bytes); |
d7d9f1612d51
writing out openssh ecc keys works
Matt Johnston <matt@ucc.asn.au>
parents:
807
diff
changeset
|
1040 |
d7d9f1612d51
writing out openssh ecc keys works
Matt Johnston <matt@ucc.asn.au>
parents:
807
diff
changeset
|
1041 /* iqmp */ |
d7d9f1612d51
writing out openssh ecc keys works
Matt Johnston <matt@ucc.asn.au>
parents:
807
diff
changeset
|
1042 numbers[8].bytes = buf_getint(extrablob); |
d7d9f1612d51
writing out openssh ecc keys works
Matt Johnston <matt@ucc.asn.au>
parents:
807
diff
changeset
|
1043 numbers[8].start = buf_getptr(extrablob, numbers[8].bytes); |
d7d9f1612d51
writing out openssh ecc keys works
Matt Johnston <matt@ucc.asn.au>
parents:
807
diff
changeset
|
1044 buf_incrpos(extrablob, numbers[8].bytes); |
4
fe6bca95afa7
Makefile.in contains updated files required
Matt Johnston <matt@ucc.asn.au>
parents:
diff
changeset
|
1045 |
836
d7d9f1612d51
writing out openssh ecc keys works
Matt Johnston <matt@ucc.asn.au>
parents:
807
diff
changeset
|
1046 nnumbers = 9; |
d7d9f1612d51
writing out openssh ecc keys works
Matt Johnston <matt@ucc.asn.au>
parents:
807
diff
changeset
|
1047 header = "-----BEGIN RSA PRIVATE KEY-----\n"; |
d7d9f1612d51
writing out openssh ecc keys works
Matt Johnston <matt@ucc.asn.au>
parents:
807
diff
changeset
|
1048 footer = "-----END RSA PRIVATE KEY-----\n"; |
4
fe6bca95afa7
Makefile.in contains updated files required
Matt Johnston <matt@ucc.asn.au>
parents:
diff
changeset
|
1049 } |
836
d7d9f1612d51
writing out openssh ecc keys works
Matt Johnston <matt@ucc.asn.au>
parents:
807
diff
changeset
|
1050 #endif /* DROPBEAR_RSA */ |
4
fe6bca95afa7
Makefile.in contains updated files required
Matt Johnston <matt@ucc.asn.au>
parents:
diff
changeset
|
1051 |
1499
2d450c1056e3
options: Complete the transition to numeric toggles (`#if')
Michael Witten <mfwitten@gmail.com>
parents:
1459
diff
changeset
|
1052 #if DROPBEAR_DSS |
836
d7d9f1612d51
writing out openssh ecc keys works
Matt Johnston <matt@ucc.asn.au>
parents:
807
diff
changeset
|
1053 if (key->type == DROPBEAR_SIGNKEY_DSS) { |
d7d9f1612d51
writing out openssh ecc keys works
Matt Johnston <matt@ucc.asn.au>
parents:
807
diff
changeset
|
1054 |
d7d9f1612d51
writing out openssh ecc keys works
Matt Johnston <matt@ucc.asn.au>
parents:
807
diff
changeset
|
1055 /* p */ |
d7d9f1612d51
writing out openssh ecc keys works
Matt Johnston <matt@ucc.asn.au>
parents:
807
diff
changeset
|
1056 numbers[1].bytes = buf_getint(keyblob); |
d7d9f1612d51
writing out openssh ecc keys works
Matt Johnston <matt@ucc.asn.au>
parents:
807
diff
changeset
|
1057 numbers[1].start = buf_getptr(keyblob, numbers[1].bytes); |
d7d9f1612d51
writing out openssh ecc keys works
Matt Johnston <matt@ucc.asn.au>
parents:
807
diff
changeset
|
1058 buf_incrpos(keyblob, numbers[1].bytes); |
d7d9f1612d51
writing out openssh ecc keys works
Matt Johnston <matt@ucc.asn.au>
parents:
807
diff
changeset
|
1059 |
d7d9f1612d51
writing out openssh ecc keys works
Matt Johnston <matt@ucc.asn.au>
parents:
807
diff
changeset
|
1060 /* q */ |
d7d9f1612d51
writing out openssh ecc keys works
Matt Johnston <matt@ucc.asn.au>
parents:
807
diff
changeset
|
1061 numbers[2].bytes = buf_getint(keyblob); |
d7d9f1612d51
writing out openssh ecc keys works
Matt Johnston <matt@ucc.asn.au>
parents:
807
diff
changeset
|
1062 numbers[2].start = buf_getptr(keyblob, numbers[2].bytes); |
d7d9f1612d51
writing out openssh ecc keys works
Matt Johnston <matt@ucc.asn.au>
parents:
807
diff
changeset
|
1063 buf_incrpos(keyblob, numbers[2].bytes); |
d7d9f1612d51
writing out openssh ecc keys works
Matt Johnston <matt@ucc.asn.au>
parents:
807
diff
changeset
|
1064 |
d7d9f1612d51
writing out openssh ecc keys works
Matt Johnston <matt@ucc.asn.au>
parents:
807
diff
changeset
|
1065 /* g */ |
d7d9f1612d51
writing out openssh ecc keys works
Matt Johnston <matt@ucc.asn.au>
parents:
807
diff
changeset
|
1066 numbers[3].bytes = buf_getint(keyblob); |
d7d9f1612d51
writing out openssh ecc keys works
Matt Johnston <matt@ucc.asn.au>
parents:
807
diff
changeset
|
1067 numbers[3].start = buf_getptr(keyblob, numbers[3].bytes); |
d7d9f1612d51
writing out openssh ecc keys works
Matt Johnston <matt@ucc.asn.au>
parents:
807
diff
changeset
|
1068 buf_incrpos(keyblob, numbers[3].bytes); |
d7d9f1612d51
writing out openssh ecc keys works
Matt Johnston <matt@ucc.asn.au>
parents:
807
diff
changeset
|
1069 |
d7d9f1612d51
writing out openssh ecc keys works
Matt Johnston <matt@ucc.asn.au>
parents:
807
diff
changeset
|
1070 /* y */ |
d7d9f1612d51
writing out openssh ecc keys works
Matt Johnston <matt@ucc.asn.au>
parents:
807
diff
changeset
|
1071 numbers[4].bytes = buf_getint(keyblob); |
d7d9f1612d51
writing out openssh ecc keys works
Matt Johnston <matt@ucc.asn.au>
parents:
807
diff
changeset
|
1072 numbers[4].start = buf_getptr(keyblob, numbers[4].bytes); |
d7d9f1612d51
writing out openssh ecc keys works
Matt Johnston <matt@ucc.asn.au>
parents:
807
diff
changeset
|
1073 buf_incrpos(keyblob, numbers[4].bytes); |
d7d9f1612d51
writing out openssh ecc keys works
Matt Johnston <matt@ucc.asn.au>
parents:
807
diff
changeset
|
1074 |
d7d9f1612d51
writing out openssh ecc keys works
Matt Johnston <matt@ucc.asn.au>
parents:
807
diff
changeset
|
1075 /* x */ |
d7d9f1612d51
writing out openssh ecc keys works
Matt Johnston <matt@ucc.asn.au>
parents:
807
diff
changeset
|
1076 numbers[5].bytes = buf_getint(keyblob); |
d7d9f1612d51
writing out openssh ecc keys works
Matt Johnston <matt@ucc.asn.au>
parents:
807
diff
changeset
|
1077 numbers[5].start = buf_getptr(keyblob, numbers[5].bytes); |
d7d9f1612d51
writing out openssh ecc keys works
Matt Johnston <matt@ucc.asn.au>
parents:
807
diff
changeset
|
1078 buf_incrpos(keyblob, numbers[5].bytes); |
d7d9f1612d51
writing out openssh ecc keys works
Matt Johnston <matt@ucc.asn.au>
parents:
807
diff
changeset
|
1079 |
d7d9f1612d51
writing out openssh ecc keys works
Matt Johnston <matt@ucc.asn.au>
parents:
807
diff
changeset
|
1080 nnumbers = 6; |
d7d9f1612d51
writing out openssh ecc keys works
Matt Johnston <matt@ucc.asn.au>
parents:
807
diff
changeset
|
1081 header = "-----BEGIN DSA PRIVATE KEY-----\n"; |
d7d9f1612d51
writing out openssh ecc keys works
Matt Johnston <matt@ucc.asn.au>
parents:
807
diff
changeset
|
1082 footer = "-----END DSA PRIVATE KEY-----\n"; |
d7d9f1612d51
writing out openssh ecc keys works
Matt Johnston <matt@ucc.asn.au>
parents:
807
diff
changeset
|
1083 } |
d7d9f1612d51
writing out openssh ecc keys works
Matt Johnston <matt@ucc.asn.au>
parents:
807
diff
changeset
|
1084 #endif /* DROPBEAR_DSS */ |
d7d9f1612d51
writing out openssh ecc keys works
Matt Johnston <matt@ucc.asn.au>
parents:
807
diff
changeset
|
1085 |
d7d9f1612d51
writing out openssh ecc keys works
Matt Johnston <matt@ucc.asn.au>
parents:
807
diff
changeset
|
1086 /* |
d7d9f1612d51
writing out openssh ecc keys works
Matt Johnston <matt@ucc.asn.au>
parents:
807
diff
changeset
|
1087 * Now count up the total size of the ASN.1 encoded integers, |
d7d9f1612d51
writing out openssh ecc keys works
Matt Johnston <matt@ucc.asn.au>
parents:
807
diff
changeset
|
1088 * so as to determine the length of the containing SEQUENCE. |
d7d9f1612d51
writing out openssh ecc keys works
Matt Johnston <matt@ucc.asn.au>
parents:
807
diff
changeset
|
1089 */ |
d7d9f1612d51
writing out openssh ecc keys works
Matt Johnston <matt@ucc.asn.au>
parents:
807
diff
changeset
|
1090 len = 0; |
d7d9f1612d51
writing out openssh ecc keys works
Matt Johnston <matt@ucc.asn.au>
parents:
807
diff
changeset
|
1091 for (i = 0; i < nnumbers; i++) { |
d7d9f1612d51
writing out openssh ecc keys works
Matt Johnston <matt@ucc.asn.au>
parents:
807
diff
changeset
|
1092 len += ber_write_id_len(NULL, 2, numbers[i].bytes, 0); |
d7d9f1612d51
writing out openssh ecc keys works
Matt Johnston <matt@ucc.asn.au>
parents:
807
diff
changeset
|
1093 len += numbers[i].bytes; |
d7d9f1612d51
writing out openssh ecc keys works
Matt Johnston <matt@ucc.asn.au>
parents:
807
diff
changeset
|
1094 } |
d7d9f1612d51
writing out openssh ecc keys works
Matt Johnston <matt@ucc.asn.au>
parents:
807
diff
changeset
|
1095 seqlen = len; |
d7d9f1612d51
writing out openssh ecc keys works
Matt Johnston <matt@ucc.asn.au>
parents:
807
diff
changeset
|
1096 /* Now add on the SEQUENCE header. */ |
d7d9f1612d51
writing out openssh ecc keys works
Matt Johnston <matt@ucc.asn.au>
parents:
807
diff
changeset
|
1097 len += ber_write_id_len(NULL, 16, seqlen, ASN1_CONSTRUCTED); |
d7d9f1612d51
writing out openssh ecc keys works
Matt Johnston <matt@ucc.asn.au>
parents:
807
diff
changeset
|
1098 /* Round up to the cipher block size, ensuring we have at least one |
d7d9f1612d51
writing out openssh ecc keys works
Matt Johnston <matt@ucc.asn.au>
parents:
807
diff
changeset
|
1099 * byte of padding (see below). */ |
d7d9f1612d51
writing out openssh ecc keys works
Matt Johnston <matt@ucc.asn.au>
parents:
807
diff
changeset
|
1100 outlen = len; |
d7d9f1612d51
writing out openssh ecc keys works
Matt Johnston <matt@ucc.asn.au>
parents:
807
diff
changeset
|
1101 if (passphrase) |
d7d9f1612d51
writing out openssh ecc keys works
Matt Johnston <matt@ucc.asn.au>
parents:
807
diff
changeset
|
1102 outlen = (outlen+8) &~ 7; |
d7d9f1612d51
writing out openssh ecc keys works
Matt Johnston <matt@ucc.asn.au>
parents:
807
diff
changeset
|
1103 |
d7d9f1612d51
writing out openssh ecc keys works
Matt Johnston <matt@ucc.asn.au>
parents:
807
diff
changeset
|
1104 /* |
d7d9f1612d51
writing out openssh ecc keys works
Matt Johnston <matt@ucc.asn.au>
parents:
807
diff
changeset
|
1105 * Now we know how big outblob needs to be. Allocate it. |
d7d9f1612d51
writing out openssh ecc keys works
Matt Johnston <matt@ucc.asn.au>
parents:
807
diff
changeset
|
1106 */ |
d7d9f1612d51
writing out openssh ecc keys works
Matt Johnston <matt@ucc.asn.au>
parents:
807
diff
changeset
|
1107 outblob = (unsigned char*)m_malloc(outlen); |
4
fe6bca95afa7
Makefile.in contains updated files required
Matt Johnston <matt@ucc.asn.au>
parents:
diff
changeset
|
1108 |
836
d7d9f1612d51
writing out openssh ecc keys works
Matt Johnston <matt@ucc.asn.au>
parents:
807
diff
changeset
|
1109 /* |
d7d9f1612d51
writing out openssh ecc keys works
Matt Johnston <matt@ucc.asn.au>
parents:
807
diff
changeset
|
1110 * And write the data into it. |
d7d9f1612d51
writing out openssh ecc keys works
Matt Johnston <matt@ucc.asn.au>
parents:
807
diff
changeset
|
1111 */ |
d7d9f1612d51
writing out openssh ecc keys works
Matt Johnston <matt@ucc.asn.au>
parents:
807
diff
changeset
|
1112 pos = 0; |
d7d9f1612d51
writing out openssh ecc keys works
Matt Johnston <matt@ucc.asn.au>
parents:
807
diff
changeset
|
1113 pos += ber_write_id_len(outblob+pos, 16, seqlen, ASN1_CONSTRUCTED); |
d7d9f1612d51
writing out openssh ecc keys works
Matt Johnston <matt@ucc.asn.au>
parents:
807
diff
changeset
|
1114 for (i = 0; i < nnumbers; i++) { |
d7d9f1612d51
writing out openssh ecc keys works
Matt Johnston <matt@ucc.asn.au>
parents:
807
diff
changeset
|
1115 pos += ber_write_id_len(outblob+pos, 2, numbers[i].bytes, 0); |
d7d9f1612d51
writing out openssh ecc keys works
Matt Johnston <matt@ucc.asn.au>
parents:
807
diff
changeset
|
1116 memcpy(outblob+pos, numbers[i].start, numbers[i].bytes); |
d7d9f1612d51
writing out openssh ecc keys works
Matt Johnston <matt@ucc.asn.au>
parents:
807
diff
changeset
|
1117 pos += numbers[i].bytes; |
d7d9f1612d51
writing out openssh ecc keys works
Matt Johnston <matt@ucc.asn.au>
parents:
807
diff
changeset
|
1118 } |
857 | 1119 } /* end RSA and DSS handling */ |
4
fe6bca95afa7
Makefile.in contains updated files required
Matt Johnston <matt@ucc.asn.au>
parents:
diff
changeset
|
1120 |
1295
750ec4ec4cbe
Convert #ifdef to #if, other build changes
Matt Johnston <matt@ucc.asn.au>
parents:
1294
diff
changeset
|
1121 #if DROPBEAR_ECDSA |
836
d7d9f1612d51
writing out openssh ecc keys works
Matt Johnston <matt@ucc.asn.au>
parents:
807
diff
changeset
|
1122 if (key->type == DROPBEAR_SIGNKEY_ECDSA_NISTP256 |
d7d9f1612d51
writing out openssh ecc keys works
Matt Johnston <matt@ucc.asn.au>
parents:
807
diff
changeset
|
1123 || key->type == DROPBEAR_SIGNKEY_ECDSA_NISTP384 |
d7d9f1612d51
writing out openssh ecc keys works
Matt Johnston <matt@ucc.asn.au>
parents:
807
diff
changeset
|
1124 || key->type == DROPBEAR_SIGNKEY_ECDSA_NISTP521) { |
d7d9f1612d51
writing out openssh ecc keys works
Matt Johnston <matt@ucc.asn.au>
parents:
807
diff
changeset
|
1125 |
d7d9f1612d51
writing out openssh ecc keys works
Matt Johnston <matt@ucc.asn.au>
parents:
807
diff
changeset
|
1126 /* SEC1 V2 appendix c.4 |
d7d9f1612d51
writing out openssh ecc keys works
Matt Johnston <matt@ucc.asn.au>
parents:
807
diff
changeset
|
1127 ECPrivateKey ::= SEQUENCE { |
d7d9f1612d51
writing out openssh ecc keys works
Matt Johnston <matt@ucc.asn.au>
parents:
807
diff
changeset
|
1128 version INTEGER { ecPrivkeyVer1(1) } (ecPrivkeyVer1), |
d7d9f1612d51
writing out openssh ecc keys works
Matt Johnston <matt@ucc.asn.au>
parents:
807
diff
changeset
|
1129 privateKey OCTET STRING, |
d7d9f1612d51
writing out openssh ecc keys works
Matt Johnston <matt@ucc.asn.au>
parents:
807
diff
changeset
|
1130 parameters [0] ECDomainParameters {{ SECGCurveNames }} OPTIONAL, |
d7d9f1612d51
writing out openssh ecc keys works
Matt Johnston <matt@ucc.asn.au>
parents:
807
diff
changeset
|
1131 publicKey [1] BIT STRING OPTIONAL |
4
fe6bca95afa7
Makefile.in contains updated files required
Matt Johnston <matt@ucc.asn.au>
parents:
diff
changeset
|
1132 } |
836
d7d9f1612d51
writing out openssh ecc keys works
Matt Johnston <matt@ucc.asn.au>
parents:
807
diff
changeset
|
1133 */ |
d7d9f1612d51
writing out openssh ecc keys works
Matt Johnston <matt@ucc.asn.au>
parents:
807
diff
changeset
|
1134 buffer *seq_buf = buf_new(400); |
846
b298bb438625
refactor key generation, make it generate as required.
Matt Johnston <matt@ucc.asn.au>
parents:
845
diff
changeset
|
1135 ecc_key **eck = (ecc_key**)signkey_key_ptr(key, key->type); |
b298bb438625
refactor key generation, make it generate as required.
Matt Johnston <matt@ucc.asn.au>
parents:
845
diff
changeset
|
1136 const long curve_size = (*eck)->dp->size; |
836
d7d9f1612d51
writing out openssh ecc keys works
Matt Johnston <matt@ucc.asn.au>
parents:
807
diff
changeset
|
1137 int curve_oid_len = 0; |
d7d9f1612d51
writing out openssh ecc keys works
Matt Johnston <matt@ucc.asn.au>
parents:
807
diff
changeset
|
1138 const void* curve_oid = NULL; |
d7d9f1612d51
writing out openssh ecc keys works
Matt Johnston <matt@ucc.asn.au>
parents:
807
diff
changeset
|
1139 unsigned long pubkey_size = 2*curve_size+1; |
1089
d144a6bece53
Uses k_size as an signed integer
Gaël PORTAY <gael.portay@gmail.com>
parents:
1045
diff
changeset
|
1140 int k_size; |
1038
d3925ed45a85
Fix for old compilers, variable declarations at beginning of functions
Thorsten Horstmann <thorsten.horstmann@web.de>
parents:
1002
diff
changeset
|
1141 int err = 0; |
4
fe6bca95afa7
Makefile.in contains updated files required
Matt Johnston <matt@ucc.asn.au>
parents:
diff
changeset
|
1142 |
836
d7d9f1612d51
writing out openssh ecc keys works
Matt Johnston <matt@ucc.asn.au>
parents:
807
diff
changeset
|
1143 /* version. less than 10 bytes */ |
d7d9f1612d51
writing out openssh ecc keys works
Matt Johnston <matt@ucc.asn.au>
parents:
807
diff
changeset
|
1144 buf_incrwritepos(seq_buf, |
d7d9f1612d51
writing out openssh ecc keys works
Matt Johnston <matt@ucc.asn.au>
parents:
807
diff
changeset
|
1145 ber_write_id_len(buf_getwriteptr(seq_buf, 10), 2, 1, 0)); |
d7d9f1612d51
writing out openssh ecc keys works
Matt Johnston <matt@ucc.asn.au>
parents:
807
diff
changeset
|
1146 buf_putbyte(seq_buf, 1); |
d7d9f1612d51
writing out openssh ecc keys works
Matt Johnston <matt@ucc.asn.au>
parents:
807
diff
changeset
|
1147 |
d7d9f1612d51
writing out openssh ecc keys works
Matt Johnston <matt@ucc.asn.au>
parents:
807
diff
changeset
|
1148 /* privateKey */ |
867
d2d624c951ca
- Increase buffer size, fixes converting 521bit ECC key
Matt Johnston <matt@ucc.asn.au>
parents:
857
diff
changeset
|
1149 k_size = mp_unsigned_bin_size((*eck)->k); |
d2d624c951ca
- Increase buffer size, fixes converting 521bit ECC key
Matt Johnston <matt@ucc.asn.au>
parents:
857
diff
changeset
|
1150 dropbear_assert(k_size <= curve_size); |
836
d7d9f1612d51
writing out openssh ecc keys works
Matt Johnston <matt@ucc.asn.au>
parents:
807
diff
changeset
|
1151 buf_incrwritepos(seq_buf, |
867
d2d624c951ca
- Increase buffer size, fixes converting 521bit ECC key
Matt Johnston <matt@ucc.asn.au>
parents:
857
diff
changeset
|
1152 ber_write_id_len(buf_getwriteptr(seq_buf, 10), 4, k_size, 0)); |
1250 | 1153 mp_to_unsigned_bin((*eck)->k, buf_getwriteptr(seq_buf, k_size)); |
867
d2d624c951ca
- Increase buffer size, fixes converting 521bit ECC key
Matt Johnston <matt@ucc.asn.au>
parents:
857
diff
changeset
|
1154 buf_incrwritepos(seq_buf, k_size); |
4
fe6bca95afa7
Makefile.in contains updated files required
Matt Johnston <matt@ucc.asn.au>
parents:
diff
changeset
|
1155 |
836
d7d9f1612d51
writing out openssh ecc keys works
Matt Johnston <matt@ucc.asn.au>
parents:
807
diff
changeset
|
1156 /* SECGCurveNames */ |
d7d9f1612d51
writing out openssh ecc keys works
Matt Johnston <matt@ucc.asn.au>
parents:
807
diff
changeset
|
1157 switch (key->type) |
d7d9f1612d51
writing out openssh ecc keys works
Matt Johnston <matt@ucc.asn.au>
parents:
807
diff
changeset
|
1158 { |
d7d9f1612d51
writing out openssh ecc keys works
Matt Johnston <matt@ucc.asn.au>
parents:
807
diff
changeset
|
1159 case DROPBEAR_SIGNKEY_ECDSA_NISTP256: |
d7d9f1612d51
writing out openssh ecc keys works
Matt Johnston <matt@ucc.asn.au>
parents:
807
diff
changeset
|
1160 curve_oid_len = sizeof(OID_SEC256R1_BLOB); |
d7d9f1612d51
writing out openssh ecc keys works
Matt Johnston <matt@ucc.asn.au>
parents:
807
diff
changeset
|
1161 curve_oid = OID_SEC256R1_BLOB; |
d7d9f1612d51
writing out openssh ecc keys works
Matt Johnston <matt@ucc.asn.au>
parents:
807
diff
changeset
|
1162 break; |
d7d9f1612d51
writing out openssh ecc keys works
Matt Johnston <matt@ucc.asn.au>
parents:
807
diff
changeset
|
1163 case DROPBEAR_SIGNKEY_ECDSA_NISTP384: |
d7d9f1612d51
writing out openssh ecc keys works
Matt Johnston <matt@ucc.asn.au>
parents:
807
diff
changeset
|
1164 curve_oid_len = sizeof(OID_SEC384R1_BLOB); |
d7d9f1612d51
writing out openssh ecc keys works
Matt Johnston <matt@ucc.asn.au>
parents:
807
diff
changeset
|
1165 curve_oid = OID_SEC384R1_BLOB; |
d7d9f1612d51
writing out openssh ecc keys works
Matt Johnston <matt@ucc.asn.au>
parents:
807
diff
changeset
|
1166 break; |
d7d9f1612d51
writing out openssh ecc keys works
Matt Johnston <matt@ucc.asn.au>
parents:
807
diff
changeset
|
1167 case DROPBEAR_SIGNKEY_ECDSA_NISTP521: |
d7d9f1612d51
writing out openssh ecc keys works
Matt Johnston <matt@ucc.asn.au>
parents:
807
diff
changeset
|
1168 curve_oid_len = sizeof(OID_SEC521R1_BLOB); |
d7d9f1612d51
writing out openssh ecc keys works
Matt Johnston <matt@ucc.asn.au>
parents:
807
diff
changeset
|
1169 curve_oid = OID_SEC521R1_BLOB; |
d7d9f1612d51
writing out openssh ecc keys works
Matt Johnston <matt@ucc.asn.au>
parents:
807
diff
changeset
|
1170 break; |
d7d9f1612d51
writing out openssh ecc keys works
Matt Johnston <matt@ucc.asn.au>
parents:
807
diff
changeset
|
1171 default: |
d7d9f1612d51
writing out openssh ecc keys works
Matt Johnston <matt@ucc.asn.au>
parents:
807
diff
changeset
|
1172 dropbear_exit("Internal error"); |
4
fe6bca95afa7
Makefile.in contains updated files required
Matt Johnston <matt@ucc.asn.au>
parents:
diff
changeset
|
1173 } |
fe6bca95afa7
Makefile.in contains updated files required
Matt Johnston <matt@ucc.asn.au>
parents:
diff
changeset
|
1174 |
836
d7d9f1612d51
writing out openssh ecc keys works
Matt Johnston <matt@ucc.asn.au>
parents:
807
diff
changeset
|
1175 buf_incrwritepos(seq_buf, |
d7d9f1612d51
writing out openssh ecc keys works
Matt Johnston <matt@ucc.asn.au>
parents:
807
diff
changeset
|
1176 ber_write_id_len(buf_getwriteptr(seq_buf, 10), 0, 2+curve_oid_len, 0xa0)); |
857 | 1177 /* object == 6 */ |
836
d7d9f1612d51
writing out openssh ecc keys works
Matt Johnston <matt@ucc.asn.au>
parents:
807
diff
changeset
|
1178 buf_incrwritepos(seq_buf, |
d7d9f1612d51
writing out openssh ecc keys works
Matt Johnston <matt@ucc.asn.au>
parents:
807
diff
changeset
|
1179 ber_write_id_len(buf_getwriteptr(seq_buf, 10), 6, curve_oid_len, 0)); |
d7d9f1612d51
writing out openssh ecc keys works
Matt Johnston <matt@ucc.asn.au>
parents:
807
diff
changeset
|
1180 buf_putbytes(seq_buf, curve_oid, curve_oid_len); |
4
fe6bca95afa7
Makefile.in contains updated files required
Matt Johnston <matt@ucc.asn.au>
parents:
diff
changeset
|
1181 |
836
d7d9f1612d51
writing out openssh ecc keys works
Matt Johnston <matt@ucc.asn.au>
parents:
807
diff
changeset
|
1182 buf_incrwritepos(seq_buf, |
1638
315fcba6960e
dropbearconvert: keyimport.c: fix BER encoding of secp521r1 keys (#69)
Christian Hohnstädt <christian@hohnstaedt.de>
parents:
1499
diff
changeset
|
1183 ber_write_id_len(buf_getwriteptr(seq_buf, 10), 1, |
315fcba6960e
dropbearconvert: keyimport.c: fix BER encoding of secp521r1 keys (#69)
Christian Hohnstädt <christian@hohnstaedt.de>
parents:
1499
diff
changeset
|
1184 (pubkey_size +1 < 128 ? 2 : 3 ) +1 +pubkey_size, 0xa0)); |
315fcba6960e
dropbearconvert: keyimport.c: fix BER encoding of secp521r1 keys (#69)
Christian Hohnstädt <christian@hohnstaedt.de>
parents:
1499
diff
changeset
|
1185 |
836
d7d9f1612d51
writing out openssh ecc keys works
Matt Johnston <matt@ucc.asn.au>
parents:
807
diff
changeset
|
1186 buf_incrwritepos(seq_buf, |
d7d9f1612d51
writing out openssh ecc keys works
Matt Johnston <matt@ucc.asn.au>
parents:
807
diff
changeset
|
1187 ber_write_id_len(buf_getwriteptr(seq_buf, 10), 3, 1+pubkey_size, 0)); |
d7d9f1612d51
writing out openssh ecc keys works
Matt Johnston <matt@ucc.asn.au>
parents:
807
diff
changeset
|
1188 buf_putbyte(seq_buf, 0); |
1038
d3925ed45a85
Fix for old compilers, variable declarations at beginning of functions
Thorsten Horstmann <thorsten.horstmann@web.de>
parents:
1002
diff
changeset
|
1189 err = ecc_ansi_x963_export(*eck, buf_getwriteptr(seq_buf, pubkey_size), &pubkey_size); |
836
d7d9f1612d51
writing out openssh ecc keys works
Matt Johnston <matt@ucc.asn.au>
parents:
807
diff
changeset
|
1190 if (err != CRYPT_OK) { |
d7d9f1612d51
writing out openssh ecc keys works
Matt Johnston <matt@ucc.asn.au>
parents:
807
diff
changeset
|
1191 dropbear_exit("ECC error"); |
d7d9f1612d51
writing out openssh ecc keys works
Matt Johnston <matt@ucc.asn.au>
parents:
807
diff
changeset
|
1192 } |
d7d9f1612d51
writing out openssh ecc keys works
Matt Johnston <matt@ucc.asn.au>
parents:
807
diff
changeset
|
1193 buf_incrwritepos(seq_buf, pubkey_size); |
4
fe6bca95afa7
Makefile.in contains updated files required
Matt Johnston <matt@ucc.asn.au>
parents:
diff
changeset
|
1194 |
836
d7d9f1612d51
writing out openssh ecc keys works
Matt Johnston <matt@ucc.asn.au>
parents:
807
diff
changeset
|
1195 buf_setpos(seq_buf, 0); |
d7d9f1612d51
writing out openssh ecc keys works
Matt Johnston <matt@ucc.asn.au>
parents:
807
diff
changeset
|
1196 |
867
d2d624c951ca
- Increase buffer size, fixes converting 521bit ECC key
Matt Johnston <matt@ucc.asn.au>
parents:
857
diff
changeset
|
1197 outblob = (unsigned char*)m_malloc(1000); |
4
fe6bca95afa7
Makefile.in contains updated files required
Matt Johnston <matt@ucc.asn.au>
parents:
diff
changeset
|
1198 |
836
d7d9f1612d51
writing out openssh ecc keys works
Matt Johnston <matt@ucc.asn.au>
parents:
807
diff
changeset
|
1199 pos = 0; |
d7d9f1612d51
writing out openssh ecc keys works
Matt Johnston <matt@ucc.asn.au>
parents:
807
diff
changeset
|
1200 pos += ber_write_id_len(outblob+pos, 16, seq_buf->len, ASN1_CONSTRUCTED); |
d7d9f1612d51
writing out openssh ecc keys works
Matt Johnston <matt@ucc.asn.au>
parents:
807
diff
changeset
|
1201 memcpy(&outblob[pos], seq_buf->data, seq_buf->len); |
d7d9f1612d51
writing out openssh ecc keys works
Matt Johnston <matt@ucc.asn.au>
parents:
807
diff
changeset
|
1202 pos += seq_buf->len; |
d7d9f1612d51
writing out openssh ecc keys works
Matt Johnston <matt@ucc.asn.au>
parents:
807
diff
changeset
|
1203 len = pos; |
d7d9f1612d51
writing out openssh ecc keys works
Matt Johnston <matt@ucc.asn.au>
parents:
807
diff
changeset
|
1204 outlen = len; |
4
fe6bca95afa7
Makefile.in contains updated files required
Matt Johnston <matt@ucc.asn.au>
parents:
diff
changeset
|
1205 |
836
d7d9f1612d51
writing out openssh ecc keys works
Matt Johnston <matt@ucc.asn.au>
parents:
807
diff
changeset
|
1206 buf_burn(seq_buf); |
d7d9f1612d51
writing out openssh ecc keys works
Matt Johnston <matt@ucc.asn.au>
parents:
807
diff
changeset
|
1207 buf_free(seq_buf); |
d7d9f1612d51
writing out openssh ecc keys works
Matt Johnston <matt@ucc.asn.au>
parents:
807
diff
changeset
|
1208 seq_buf = NULL; |
d7d9f1612d51
writing out openssh ecc keys works
Matt Johnston <matt@ucc.asn.au>
parents:
807
diff
changeset
|
1209 |
d7d9f1612d51
writing out openssh ecc keys works
Matt Johnston <matt@ucc.asn.au>
parents:
807
diff
changeset
|
1210 header = "-----BEGIN EC PRIVATE KEY-----\n"; |
d7d9f1612d51
writing out openssh ecc keys works
Matt Johnston <matt@ucc.asn.au>
parents:
807
diff
changeset
|
1211 footer = "-----END EC PRIVATE KEY-----\n"; |
4
fe6bca95afa7
Makefile.in contains updated files required
Matt Johnston <matt@ucc.asn.au>
parents:
diff
changeset
|
1212 } |
836
d7d9f1612d51
writing out openssh ecc keys works
Matt Johnston <matt@ucc.asn.au>
parents:
807
diff
changeset
|
1213 #endif |
4
fe6bca95afa7
Makefile.in contains updated files required
Matt Johnston <matt@ucc.asn.au>
parents:
diff
changeset
|
1214 |
1659
d32bcb5c557d
Add Ed25519 support (#91)
Vladislav Grishenko <themiron@users.noreply.github.com>
parents:
1638
diff
changeset
|
1215 #if DROPBEAR_ED25519 |
d32bcb5c557d
Add Ed25519 support (#91)
Vladislav Grishenko <themiron@users.noreply.github.com>
parents:
1638
diff
changeset
|
1216 if (key->type == DROPBEAR_SIGNKEY_ED25519) { |
d32bcb5c557d
Add Ed25519 support (#91)
Vladislav Grishenko <themiron@users.noreply.github.com>
parents:
1638
diff
changeset
|
1217 buffer *buf = buf_new(300); |
d32bcb5c557d
Add Ed25519 support (#91)
Vladislav Grishenko <themiron@users.noreply.github.com>
parents:
1638
diff
changeset
|
1218 keyblob = buf_new(100); |
d32bcb5c557d
Add Ed25519 support (#91)
Vladislav Grishenko <themiron@users.noreply.github.com>
parents:
1638
diff
changeset
|
1219 extrablob = buf_new(200); |
d32bcb5c557d
Add Ed25519 support (#91)
Vladislav Grishenko <themiron@users.noreply.github.com>
parents:
1638
diff
changeset
|
1220 |
d32bcb5c557d
Add Ed25519 support (#91)
Vladislav Grishenko <themiron@users.noreply.github.com>
parents:
1638
diff
changeset
|
1221 /* private key blob w/o header */ |
d32bcb5c557d
Add Ed25519 support (#91)
Vladislav Grishenko <themiron@users.noreply.github.com>
parents:
1638
diff
changeset
|
1222 buf_put_priv_key(keyblob, key, key->type); |
d32bcb5c557d
Add Ed25519 support (#91)
Vladislav Grishenko <themiron@users.noreply.github.com>
parents:
1638
diff
changeset
|
1223 buf_setpos(keyblob, 0); |
d32bcb5c557d
Add Ed25519 support (#91)
Vladislav Grishenko <themiron@users.noreply.github.com>
parents:
1638
diff
changeset
|
1224 buf_incrpos(keyblob, buf_getint(keyblob)); |
d32bcb5c557d
Add Ed25519 support (#91)
Vladislav Grishenko <themiron@users.noreply.github.com>
parents:
1638
diff
changeset
|
1225 len = buf_getint(keyblob); |
d32bcb5c557d
Add Ed25519 support (#91)
Vladislav Grishenko <themiron@users.noreply.github.com>
parents:
1638
diff
changeset
|
1226 |
d32bcb5c557d
Add Ed25519 support (#91)
Vladislav Grishenko <themiron@users.noreply.github.com>
parents:
1638
diff
changeset
|
1227 /* header */ |
d32bcb5c557d
Add Ed25519 support (#91)
Vladislav Grishenko <themiron@users.noreply.github.com>
parents:
1638
diff
changeset
|
1228 buf_putbytes(buf, OSSH_PKEY_BLOB, OSSH_PKEY_BLOBLEN); |
d32bcb5c557d
Add Ed25519 support (#91)
Vladislav Grishenko <themiron@users.noreply.github.com>
parents:
1638
diff
changeset
|
1229 |
d32bcb5c557d
Add Ed25519 support (#91)
Vladislav Grishenko <themiron@users.noreply.github.com>
parents:
1638
diff
changeset
|
1230 /* public key */ |
d32bcb5c557d
Add Ed25519 support (#91)
Vladislav Grishenko <themiron@users.noreply.github.com>
parents:
1638
diff
changeset
|
1231 buf_put_pub_key(buf, key, key->type); |
d32bcb5c557d
Add Ed25519 support (#91)
Vladislav Grishenko <themiron@users.noreply.github.com>
parents:
1638
diff
changeset
|
1232 |
d32bcb5c557d
Add Ed25519 support (#91)
Vladislav Grishenko <themiron@users.noreply.github.com>
parents:
1638
diff
changeset
|
1233 /* private key */ |
d32bcb5c557d
Add Ed25519 support (#91)
Vladislav Grishenko <themiron@users.noreply.github.com>
parents:
1638
diff
changeset
|
1234 buf_incrwritepos(extrablob, 4); |
d32bcb5c557d
Add Ed25519 support (#91)
Vladislav Grishenko <themiron@users.noreply.github.com>
parents:
1638
diff
changeset
|
1235 buf_put_pub_key(extrablob, key, key->type); |
d32bcb5c557d
Add Ed25519 support (#91)
Vladislav Grishenko <themiron@users.noreply.github.com>
parents:
1638
diff
changeset
|
1236 buf_putstring(extrablob, buf_getptr(keyblob, len), len); |
d32bcb5c557d
Add Ed25519 support (#91)
Vladislav Grishenko <themiron@users.noreply.github.com>
parents:
1638
diff
changeset
|
1237 /* comment */ |
d32bcb5c557d
Add Ed25519 support (#91)
Vladislav Grishenko <themiron@users.noreply.github.com>
parents:
1638
diff
changeset
|
1238 buf_putstring(extrablob, "", 0); |
d32bcb5c557d
Add Ed25519 support (#91)
Vladislav Grishenko <themiron@users.noreply.github.com>
parents:
1638
diff
changeset
|
1239 /* padding to cipher block length */ |
d32bcb5c557d
Add Ed25519 support (#91)
Vladislav Grishenko <themiron@users.noreply.github.com>
parents:
1638
diff
changeset
|
1240 len = (extrablob->len+8) & ~7; |
d32bcb5c557d
Add Ed25519 support (#91)
Vladislav Grishenko <themiron@users.noreply.github.com>
parents:
1638
diff
changeset
|
1241 for (i = 1; len - extrablob->len > 0; i++) |
d32bcb5c557d
Add Ed25519 support (#91)
Vladislav Grishenko <themiron@users.noreply.github.com>
parents:
1638
diff
changeset
|
1242 buf_putbyte(extrablob, i); |
d32bcb5c557d
Add Ed25519 support (#91)
Vladislav Grishenko <themiron@users.noreply.github.com>
parents:
1638
diff
changeset
|
1243 buf_setpos(extrablob, 0); |
d32bcb5c557d
Add Ed25519 support (#91)
Vladislav Grishenko <themiron@users.noreply.github.com>
parents:
1638
diff
changeset
|
1244 buf_putbytes(extrablob, "\0\0\0\0\0\0\0\0", 8); |
d32bcb5c557d
Add Ed25519 support (#91)
Vladislav Grishenko <themiron@users.noreply.github.com>
parents:
1638
diff
changeset
|
1245 buf_putbufstring(buf, extrablob); |
d32bcb5c557d
Add Ed25519 support (#91)
Vladislav Grishenko <themiron@users.noreply.github.com>
parents:
1638
diff
changeset
|
1246 |
d32bcb5c557d
Add Ed25519 support (#91)
Vladislav Grishenko <themiron@users.noreply.github.com>
parents:
1638
diff
changeset
|
1247 outlen = len = pos = buf->len; |
d32bcb5c557d
Add Ed25519 support (#91)
Vladislav Grishenko <themiron@users.noreply.github.com>
parents:
1638
diff
changeset
|
1248 outblob = (unsigned char*)m_malloc(outlen); |
d32bcb5c557d
Add Ed25519 support (#91)
Vladislav Grishenko <themiron@users.noreply.github.com>
parents:
1638
diff
changeset
|
1249 memcpy(outblob, buf->data, buf->len); |
d32bcb5c557d
Add Ed25519 support (#91)
Vladislav Grishenko <themiron@users.noreply.github.com>
parents:
1638
diff
changeset
|
1250 |
d32bcb5c557d
Add Ed25519 support (#91)
Vladislav Grishenko <themiron@users.noreply.github.com>
parents:
1638
diff
changeset
|
1251 buf_burn(buf); |
d32bcb5c557d
Add Ed25519 support (#91)
Vladislav Grishenko <themiron@users.noreply.github.com>
parents:
1638
diff
changeset
|
1252 buf_free(buf); |
d32bcb5c557d
Add Ed25519 support (#91)
Vladislav Grishenko <themiron@users.noreply.github.com>
parents:
1638
diff
changeset
|
1253 buf = NULL; |
d32bcb5c557d
Add Ed25519 support (#91)
Vladislav Grishenko <themiron@users.noreply.github.com>
parents:
1638
diff
changeset
|
1254 |
d32bcb5c557d
Add Ed25519 support (#91)
Vladislav Grishenko <themiron@users.noreply.github.com>
parents:
1638
diff
changeset
|
1255 header = "-----BEGIN OPENSSH PRIVATE KEY-----\n"; |
d32bcb5c557d
Add Ed25519 support (#91)
Vladislav Grishenko <themiron@users.noreply.github.com>
parents:
1638
diff
changeset
|
1256 footer = "-----END OPENSSH PRIVATE KEY-----\n"; |
d32bcb5c557d
Add Ed25519 support (#91)
Vladislav Grishenko <themiron@users.noreply.github.com>
parents:
1638
diff
changeset
|
1257 } |
d32bcb5c557d
Add Ed25519 support (#91)
Vladislav Grishenko <themiron@users.noreply.github.com>
parents:
1638
diff
changeset
|
1258 #endif |
d32bcb5c557d
Add Ed25519 support (#91)
Vladislav Grishenko <themiron@users.noreply.github.com>
parents:
1638
diff
changeset
|
1259 |
1308 | 1260 /* |
1261 * Padding on OpenSSH keys is deterministic. The number of | |
1262 * padding bytes is always more than zero, and always at most | |
1263 * the cipher block length. The value of each padding byte is | |
1264 * equal to the number of padding bytes. So a plaintext that's | |
1265 * an exact multiple of the block size will be padded with 08 | |
1266 * 08 08 08 08 08 08 08 (assuming a 64-bit block cipher); a | |
1267 * plaintext one byte less than a multiple of the block size | |
1268 * will be padded with just 01. | |
1269 * | |
1270 * This enables the OpenSSL key decryption function to strip | |
1271 * off the padding algorithmically and return the unpadded | |
1272 * plaintext to the next layer: it looks at the final byte, and | |
1273 * then expects to find that many bytes at the end of the data | |
1274 * with the same value. Those are all removed and the rest is | |
1275 * returned. | |
1276 */ | |
241
c5d3ef11155f
* use own assertions which should get logged properly
Matt Johnston <matt@ucc.asn.au>
parents:
87
diff
changeset
|
1277 dropbear_assert(pos == len); |
1308 | 1278 while (pos < outlen) { |
1279 outblob[pos++] = outlen - len; | |
1280 } | |
4
fe6bca95afa7
Makefile.in contains updated files required
Matt Johnston <matt@ucc.asn.au>
parents:
diff
changeset
|
1281 |
1308 | 1282 /* |
1283 * Encrypt the key. | |
1284 */ | |
1285 if (passphrase) { | |
4
fe6bca95afa7
Makefile.in contains updated files required
Matt Johnston <matt@ucc.asn.au>
parents:
diff
changeset
|
1286 fprintf(stderr, "Encrypted keys aren't supported currently\n"); |
fe6bca95afa7
Makefile.in contains updated files required
Matt Johnston <matt@ucc.asn.au>
parents:
diff
changeset
|
1287 goto error; |
1308 | 1288 } |
4
fe6bca95afa7
Makefile.in contains updated files required
Matt Johnston <matt@ucc.asn.au>
parents:
diff
changeset
|
1289 |
1308 | 1290 /* |
1291 * And save it. We'll use Unix line endings just in case it's | |
1292 * subsequently transferred in binary mode. | |
1293 */ | |
4
fe6bca95afa7
Makefile.in contains updated files required
Matt Johnston <matt@ucc.asn.au>
parents:
diff
changeset
|
1294 if (strlen(filename) == 1 && filename[0] == '-') { |
fe6bca95afa7
Makefile.in contains updated files required
Matt Johnston <matt@ucc.asn.au>
parents:
diff
changeset
|
1295 fp = stdout; |
fe6bca95afa7
Makefile.in contains updated files required
Matt Johnston <matt@ucc.asn.au>
parents:
diff
changeset
|
1296 } else { |
fe6bca95afa7
Makefile.in contains updated files required
Matt Johnston <matt@ucc.asn.au>
parents:
diff
changeset
|
1297 fp = fopen(filename, "wb"); /* ensure Unix line endings */ |
fe6bca95afa7
Makefile.in contains updated files required
Matt Johnston <matt@ucc.asn.au>
parents:
diff
changeset
|
1298 } |
fe6bca95afa7
Makefile.in contains updated files required
Matt Johnston <matt@ucc.asn.au>
parents:
diff
changeset
|
1299 if (!fp) { |
fe6bca95afa7
Makefile.in contains updated files required
Matt Johnston <matt@ucc.asn.au>
parents:
diff
changeset
|
1300 fprintf(stderr, "Failed opening output file\n"); |
1308 | 1301 goto error; |
4
fe6bca95afa7
Makefile.in contains updated files required
Matt Johnston <matt@ucc.asn.au>
parents:
diff
changeset
|
1302 } |
1308 | 1303 fputs(header, fp); |
4
fe6bca95afa7
Makefile.in contains updated files required
Matt Johnston <matt@ucc.asn.au>
parents:
diff
changeset
|
1304 base64_encode_fp(fp, outblob, outlen, 64); |
1308 | 1305 fputs(footer, fp); |
1306 fclose(fp); | |
1307 ret = 1; | |
1308 | |
1309 error: | |
1310 if (outblob) { | |
1311 memset(outblob, 0, outlen); | |
1312 m_free(outblob); | |
4
fe6bca95afa7
Makefile.in contains updated files required
Matt Johnston <matt@ucc.asn.au>
parents:
diff
changeset
|
1313 } |
fe6bca95afa7
Makefile.in contains updated files required
Matt Johnston <matt@ucc.asn.au>
parents:
diff
changeset
|
1314 if (keyblob) { |
fe6bca95afa7
Makefile.in contains updated files required
Matt Johnston <matt@ucc.asn.au>
parents:
diff
changeset
|
1315 buf_burn(keyblob); |
fe6bca95afa7
Makefile.in contains updated files required
Matt Johnston <matt@ucc.asn.au>
parents:
diff
changeset
|
1316 buf_free(keyblob); |
1308 | 1317 } |
4
fe6bca95afa7
Makefile.in contains updated files required
Matt Johnston <matt@ucc.asn.au>
parents:
diff
changeset
|
1318 if (extrablob) { |
fe6bca95afa7
Makefile.in contains updated files required
Matt Johnston <matt@ucc.asn.au>
parents:
diff
changeset
|
1319 buf_burn(extrablob); |
fe6bca95afa7
Makefile.in contains updated files required
Matt Johnston <matt@ucc.asn.au>
parents:
diff
changeset
|
1320 buf_free(extrablob); |
1308 | 1321 } |
1322 return ret; | |
4
fe6bca95afa7
Makefile.in contains updated files required
Matt Johnston <matt@ucc.asn.au>
parents:
diff
changeset
|
1323 } |
fe6bca95afa7
Makefile.in contains updated files required
Matt Johnston <matt@ucc.asn.au>
parents:
diff
changeset
|
1324 |
fe6bca95afa7
Makefile.in contains updated files required
Matt Johnston <matt@ucc.asn.au>
parents:
diff
changeset
|
1325 #if 0 |
fe6bca95afa7
Makefile.in contains updated files required
Matt Johnston <matt@ucc.asn.au>
parents:
diff
changeset
|
1326 /* XXX TODO ssh.com stuff isn't going yet */ |
fe6bca95afa7
Makefile.in contains updated files required
Matt Johnston <matt@ucc.asn.au>
parents:
diff
changeset
|
1327 |
fe6bca95afa7
Makefile.in contains updated files required
Matt Johnston <matt@ucc.asn.au>
parents:
diff
changeset
|
1328 /* ---------------------------------------------------------------------- |
fe6bca95afa7
Makefile.in contains updated files required
Matt Johnston <matt@ucc.asn.au>
parents:
diff
changeset
|
1329 * Code to read ssh.com private keys. |
fe6bca95afa7
Makefile.in contains updated files required
Matt Johnston <matt@ucc.asn.au>
parents:
diff
changeset
|
1330 */ |
fe6bca95afa7
Makefile.in contains updated files required
Matt Johnston <matt@ucc.asn.au>
parents:
diff
changeset
|
1331 |
fe6bca95afa7
Makefile.in contains updated files required
Matt Johnston <matt@ucc.asn.au>
parents:
diff
changeset
|
1332 /* |
fe6bca95afa7
Makefile.in contains updated files required
Matt Johnston <matt@ucc.asn.au>
parents:
diff
changeset
|
1333 * The format of the base64 blob is largely ssh2-packet-formatted, |
fe6bca95afa7
Makefile.in contains updated files required
Matt Johnston <matt@ucc.asn.au>
parents:
diff
changeset
|
1334 * except that mpints are a bit different: they're more like the |
fe6bca95afa7
Makefile.in contains updated files required
Matt Johnston <matt@ucc.asn.au>
parents:
diff
changeset
|
1335 * old ssh1 mpint. You have a 32-bit bit count N, followed by |
fe6bca95afa7
Makefile.in contains updated files required
Matt Johnston <matt@ucc.asn.au>
parents:
diff
changeset
|
1336 * (N+7)/8 bytes of data. |
fe6bca95afa7
Makefile.in contains updated files required
Matt Johnston <matt@ucc.asn.au>
parents:
diff
changeset
|
1337 * |
fe6bca95afa7
Makefile.in contains updated files required
Matt Johnston <matt@ucc.asn.au>
parents:
diff
changeset
|
1338 * So. The blob contains: |
fe6bca95afa7
Makefile.in contains updated files required
Matt Johnston <matt@ucc.asn.au>
parents:
diff
changeset
|
1339 * |
fe6bca95afa7
Makefile.in contains updated files required
Matt Johnston <matt@ucc.asn.au>
parents:
diff
changeset
|
1340 * - uint32 0x3f6ff9eb (magic number) |
fe6bca95afa7
Makefile.in contains updated files required
Matt Johnston <matt@ucc.asn.au>
parents:
diff
changeset
|
1341 * - uint32 size (total blob size) |
fe6bca95afa7
Makefile.in contains updated files required
Matt Johnston <matt@ucc.asn.au>
parents:
diff
changeset
|
1342 * - string key-type (see below) |
fe6bca95afa7
Makefile.in contains updated files required
Matt Johnston <matt@ucc.asn.au>
parents:
diff
changeset
|
1343 * - string cipher-type (tells you if key is encrypted) |
fe6bca95afa7
Makefile.in contains updated files required
Matt Johnston <matt@ucc.asn.au>
parents:
diff
changeset
|
1344 * - string encrypted-blob |
fe6bca95afa7
Makefile.in contains updated files required
Matt Johnston <matt@ucc.asn.au>
parents:
diff
changeset
|
1345 * |
fe6bca95afa7
Makefile.in contains updated files required
Matt Johnston <matt@ucc.asn.au>
parents:
diff
changeset
|
1346 * (The first size field includes the size field itself and the |
fe6bca95afa7
Makefile.in contains updated files required
Matt Johnston <matt@ucc.asn.au>
parents:
diff
changeset
|
1347 * magic number before it. All other size fields are ordinary ssh2 |
fe6bca95afa7
Makefile.in contains updated files required
Matt Johnston <matt@ucc.asn.au>
parents:
diff
changeset
|
1348 * strings, so the size field indicates how much data is to |
fe6bca95afa7
Makefile.in contains updated files required
Matt Johnston <matt@ucc.asn.au>
parents:
diff
changeset
|
1349 * _follow_.) |
fe6bca95afa7
Makefile.in contains updated files required
Matt Johnston <matt@ucc.asn.au>
parents:
diff
changeset
|
1350 * |
fe6bca95afa7
Makefile.in contains updated files required
Matt Johnston <matt@ucc.asn.au>
parents:
diff
changeset
|
1351 * The encrypted blob, once decrypted, contains a single string |
fe6bca95afa7
Makefile.in contains updated files required
Matt Johnston <matt@ucc.asn.au>
parents:
diff
changeset
|
1352 * which in turn contains the payload. (This allows padding to be |
fe6bca95afa7
Makefile.in contains updated files required
Matt Johnston <matt@ucc.asn.au>
parents:
diff
changeset
|
1353 * added after that string while still making it clear where the |
fe6bca95afa7
Makefile.in contains updated files required
Matt Johnston <matt@ucc.asn.au>
parents:
diff
changeset
|
1354 * real payload ends. Also it probably makes for a reasonable |
fe6bca95afa7
Makefile.in contains updated files required
Matt Johnston <matt@ucc.asn.au>
parents:
diff
changeset
|
1355 * decryption check.) |
fe6bca95afa7
Makefile.in contains updated files required
Matt Johnston <matt@ucc.asn.au>
parents:
diff
changeset
|
1356 * |
fe6bca95afa7
Makefile.in contains updated files required
Matt Johnston <matt@ucc.asn.au>
parents:
diff
changeset
|
1357 * The payload blob, for an RSA key, contains: |
fe6bca95afa7
Makefile.in contains updated files required
Matt Johnston <matt@ucc.asn.au>
parents:
diff
changeset
|
1358 * - mpint e |
fe6bca95afa7
Makefile.in contains updated files required
Matt Johnston <matt@ucc.asn.au>
parents:
diff
changeset
|
1359 * - mpint d |
fe6bca95afa7
Makefile.in contains updated files required
Matt Johnston <matt@ucc.asn.au>
parents:
diff
changeset
|
1360 * - mpint n (yes, the public and private stuff is intermixed) |
fe6bca95afa7
Makefile.in contains updated files required
Matt Johnston <matt@ucc.asn.au>
parents:
diff
changeset
|
1361 * - mpint u (presumably inverse of p mod q) |
fe6bca95afa7
Makefile.in contains updated files required
Matt Johnston <matt@ucc.asn.au>
parents:
diff
changeset
|
1362 * - mpint p (p is the smaller prime) |
fe6bca95afa7
Makefile.in contains updated files required
Matt Johnston <matt@ucc.asn.au>
parents:
diff
changeset
|
1363 * - mpint q (q is the larger) |
fe6bca95afa7
Makefile.in contains updated files required
Matt Johnston <matt@ucc.asn.au>
parents:
diff
changeset
|
1364 * |
fe6bca95afa7
Makefile.in contains updated files required
Matt Johnston <matt@ucc.asn.au>
parents:
diff
changeset
|
1365 * For a DSA key, the payload blob contains: |
fe6bca95afa7
Makefile.in contains updated files required
Matt Johnston <matt@ucc.asn.au>
parents:
diff
changeset
|
1366 * - uint32 0 |
fe6bca95afa7
Makefile.in contains updated files required
Matt Johnston <matt@ucc.asn.au>
parents:
diff
changeset
|
1367 * - mpint p |
fe6bca95afa7
Makefile.in contains updated files required
Matt Johnston <matt@ucc.asn.au>
parents:
diff
changeset
|
1368 * - mpint g |
fe6bca95afa7
Makefile.in contains updated files required
Matt Johnston <matt@ucc.asn.au>
parents:
diff
changeset
|
1369 * - mpint q |
fe6bca95afa7
Makefile.in contains updated files required
Matt Johnston <matt@ucc.asn.au>
parents:
diff
changeset
|
1370 * - mpint y |
fe6bca95afa7
Makefile.in contains updated files required
Matt Johnston <matt@ucc.asn.au>
parents:
diff
changeset
|
1371 * - mpint x |
fe6bca95afa7
Makefile.in contains updated files required
Matt Johnston <matt@ucc.asn.au>
parents:
diff
changeset
|
1372 * |
fe6bca95afa7
Makefile.in contains updated files required
Matt Johnston <matt@ucc.asn.au>
parents:
diff
changeset
|
1373 * Alternatively, if the parameters are `predefined', that |
fe6bca95afa7
Makefile.in contains updated files required
Matt Johnston <matt@ucc.asn.au>
parents:
diff
changeset
|
1374 * (0,p,g,q) sequence can be replaced by a uint32 1 and a string |
fe6bca95afa7
Makefile.in contains updated files required
Matt Johnston <matt@ucc.asn.au>
parents:
diff
changeset
|
1375 * containing some predefined parameter specification. *shudder*, |
fe6bca95afa7
Makefile.in contains updated files required
Matt Johnston <matt@ucc.asn.au>
parents:
diff
changeset
|
1376 * but I doubt we'll encounter this in real life. |
fe6bca95afa7
Makefile.in contains updated files required
Matt Johnston <matt@ucc.asn.au>
parents:
diff
changeset
|
1377 * |
fe6bca95afa7
Makefile.in contains updated files required
Matt Johnston <matt@ucc.asn.au>
parents:
diff
changeset
|
1378 * The key type strings are ghastly. The RSA key I looked at had a |
fe6bca95afa7
Makefile.in contains updated files required
Matt Johnston <matt@ucc.asn.au>
parents:
diff
changeset
|
1379 * type string of |
fe6bca95afa7
Makefile.in contains updated files required
Matt Johnston <matt@ucc.asn.au>
parents:
diff
changeset
|
1380 * |
fe6bca95afa7
Makefile.in contains updated files required
Matt Johnston <matt@ucc.asn.au>
parents:
diff
changeset
|
1381 * `if-modn{sign{rsa-pkcs1-sha1},encrypt{rsa-pkcs1v2-oaep}}' |
fe6bca95afa7
Makefile.in contains updated files required
Matt Johnston <matt@ucc.asn.au>
parents:
diff
changeset
|
1382 * |
fe6bca95afa7
Makefile.in contains updated files required
Matt Johnston <matt@ucc.asn.au>
parents:
diff
changeset
|
1383 * and the DSA key wasn't much better: |
fe6bca95afa7
Makefile.in contains updated files required
Matt Johnston <matt@ucc.asn.au>
parents:
diff
changeset
|
1384 * |
fe6bca95afa7
Makefile.in contains updated files required
Matt Johnston <matt@ucc.asn.au>
parents:
diff
changeset
|
1385 * `dl-modp{sign{dsa-nist-sha1},dh{plain}}' |
fe6bca95afa7
Makefile.in contains updated files required
Matt Johnston <matt@ucc.asn.au>
parents:
diff
changeset
|
1386 * |
fe6bca95afa7
Makefile.in contains updated files required
Matt Johnston <matt@ucc.asn.au>
parents:
diff
changeset
|
1387 * It isn't clear that these will always be the same. I think it |
fe6bca95afa7
Makefile.in contains updated files required
Matt Johnston <matt@ucc.asn.au>
parents:
diff
changeset
|
1388 * might be wise just to look at the `if-modn{sign{rsa' and |
fe6bca95afa7
Makefile.in contains updated files required
Matt Johnston <matt@ucc.asn.au>
parents:
diff
changeset
|
1389 * `dl-modp{sign{dsa' prefixes. |
fe6bca95afa7
Makefile.in contains updated files required
Matt Johnston <matt@ucc.asn.au>
parents:
diff
changeset
|
1390 * |
fe6bca95afa7
Makefile.in contains updated files required
Matt Johnston <matt@ucc.asn.au>
parents:
diff
changeset
|
1391 * Finally, the encryption. The cipher-type string appears to be |
fe6bca95afa7
Makefile.in contains updated files required
Matt Johnston <matt@ucc.asn.au>
parents:
diff
changeset
|
1392 * either `none' or `3des-cbc'. Looks as if this is SSH2-style |
fe6bca95afa7
Makefile.in contains updated files required
Matt Johnston <matt@ucc.asn.au>
parents:
diff
changeset
|
1393 * 3des-cbc (i.e. outer cbc rather than inner). The key is created |
fe6bca95afa7
Makefile.in contains updated files required
Matt Johnston <matt@ucc.asn.au>
parents:
diff
changeset
|
1394 * from the passphrase by means of yet another hashing faff: |
fe6bca95afa7
Makefile.in contains updated files required
Matt Johnston <matt@ucc.asn.au>
parents:
diff
changeset
|
1395 * |
fe6bca95afa7
Makefile.in contains updated files required
Matt Johnston <matt@ucc.asn.au>
parents:
diff
changeset
|
1396 * - first 16 bytes are MD5(passphrase) |
fe6bca95afa7
Makefile.in contains updated files required
Matt Johnston <matt@ucc.asn.au>
parents:
diff
changeset
|
1397 * - next 16 bytes are MD5(passphrase || first 16 bytes) |
fe6bca95afa7
Makefile.in contains updated files required
Matt Johnston <matt@ucc.asn.au>
parents:
diff
changeset
|
1398 * - if there were more, they'd be MD5(passphrase || first 32), |
fe6bca95afa7
Makefile.in contains updated files required
Matt Johnston <matt@ucc.asn.au>
parents:
diff
changeset
|
1399 * and so on. |
fe6bca95afa7
Makefile.in contains updated files required
Matt Johnston <matt@ucc.asn.au>
parents:
diff
changeset
|
1400 */ |
fe6bca95afa7
Makefile.in contains updated files required
Matt Johnston <matt@ucc.asn.au>
parents:
diff
changeset
|
1401 |
fe6bca95afa7
Makefile.in contains updated files required
Matt Johnston <matt@ucc.asn.au>
parents:
diff
changeset
|
1402 #define SSHCOM_MAGIC_NUMBER 0x3f6ff9eb |
fe6bca95afa7
Makefile.in contains updated files required
Matt Johnston <matt@ucc.asn.au>
parents:
diff
changeset
|
1403 |
fe6bca95afa7
Makefile.in contains updated files required
Matt Johnston <matt@ucc.asn.au>
parents:
diff
changeset
|
1404 struct sshcom_key { |
fe6bca95afa7
Makefile.in contains updated files required
Matt Johnston <matt@ucc.asn.au>
parents:
diff
changeset
|
1405 char comment[256]; /* allowing any length is overkill */ |
1308 | 1406 unsigned char *keyblob; |
1407 int keyblob_len, keyblob_size; | |
4
fe6bca95afa7
Makefile.in contains updated files required
Matt Johnston <matt@ucc.asn.au>
parents:
diff
changeset
|
1408 }; |
fe6bca95afa7
Makefile.in contains updated files required
Matt Johnston <matt@ucc.asn.au>
parents:
diff
changeset
|
1409 |
fe6bca95afa7
Makefile.in contains updated files required
Matt Johnston <matt@ucc.asn.au>
parents:
diff
changeset
|
1410 static struct sshcom_key *load_sshcom_key(const char *filename) |
fe6bca95afa7
Makefile.in contains updated files required
Matt Johnston <matt@ucc.asn.au>
parents:
diff
changeset
|
1411 { |
1308 | 1412 struct sshcom_key *ret; |
1413 FILE *fp; | |
1414 char buffer[256]; | |
1415 int len; | |
1416 char *errmsg, *p; | |
1417 int headers_done; | |
1418 char base64_bit[4]; | |
1419 int base64_chars = 0; | |
4
fe6bca95afa7
Makefile.in contains updated files required
Matt Johnston <matt@ucc.asn.au>
parents:
diff
changeset
|
1420 |
1308 | 1421 ret = snew(struct sshcom_key); |
1422 ret->comment[0] = '\0'; | |
1423 ret->keyblob = NULL; | |
1424 ret->keyblob_len = ret->keyblob_size = 0; | |
4
fe6bca95afa7
Makefile.in contains updated files required
Matt Johnston <matt@ucc.asn.au>
parents:
diff
changeset
|
1425 |
fe6bca95afa7
Makefile.in contains updated files required
Matt Johnston <matt@ucc.asn.au>
parents:
diff
changeset
|
1426 fp = fopen(filename, "r"); |
1308 | 1427 if (!fp) { |
1428 errmsg = "Unable to open key file"; | |
1429 goto error; | |
1306
34e6127ef02e
merge fixes from PuTTY import.c
Matt Johnston <matt@ucc.asn.au>
parents:
1250
diff
changeset
|
1430 } |
1308 | 1431 if (!fgets(buffer, sizeof(buffer), fp) || |
1432 0 != strcmp(buffer, "---- BEGIN SSH2 ENCRYPTED PRIVATE KEY ----\n")) { | |
1433 errmsg = "File does not begin with ssh.com key header"; | |
1306
34e6127ef02e
merge fixes from PuTTY import.c
Matt Johnston <matt@ucc.asn.au>
parents:
1250
diff
changeset
|
1434 goto error; |
1308 | 1435 } |
4
fe6bca95afa7
Makefile.in contains updated files required
Matt Johnston <matt@ucc.asn.au>
parents:
diff
changeset
|
1436 |
1308 | 1437 headers_done = 0; |
1438 while (1) { | |
1439 if (!fgets(buffer, sizeof(buffer), fp)) { | |
1440 errmsg = "Unexpected end of file"; | |
1441 goto error; | |
1442 } | |
1443 if (!strcmp(buffer, "---- END SSH2 ENCRYPTED PRIVATE KEY ----\n")) | |
4
fe6bca95afa7
Makefile.in contains updated files required
Matt Johnston <matt@ucc.asn.au>
parents:
diff
changeset
|
1444 break; /* done */ |
1308 | 1445 if ((p = strchr(buffer, ':')) != NULL) { |
1446 if (headers_done) { | |
1447 errmsg = "Header found in body of key data"; | |
1448 goto error; | |
1449 } | |
1450 *p++ = '\0'; | |
1451 while (*p && isspace((unsigned char)*p)) p++; | |
1452 /* | |
1453 * Header lines can end in a trailing backslash for | |
1454 * continuation. | |
1455 */ | |
1456 while ((len = strlen(p)) > (int)(sizeof(buffer) - (p-buffer) -1) || | |
1457 p[len-1] != '\n' || p[len-2] == '\\') { | |
1458 if (len > (int)((p-buffer) + sizeof(buffer)-2)) { | |
1459 errmsg = "Header line too long to deal with"; | |
1460 goto error; | |
1461 } | |
1462 if (!fgets(p+len-2, sizeof(buffer)-(p-buffer)-(len-2), fp)) { | |
1463 errmsg = "Unexpected end of file"; | |
1464 goto error; | |
1465 } | |
1466 } | |
1467 p[strcspn(p, "\n")] = '\0'; | |
1468 if (!strcmp(buffer, "Comment")) { | |
1469 /* Strip quotes in comment if present. */ | |
1470 if (p[0] == '"' && p[strlen(p)-1] == '"') { | |
1471 p++; | |
1472 p[strlen(p)-1] = '\0'; | |
1473 } | |
1474 strncpy(ret->comment, p, sizeof(ret->comment)); | |
1475 ret->comment[sizeof(ret->comment)-1] = '\0'; | |
1476 } | |
1477 } else { | |
1478 headers_done = 1; | |
4
fe6bca95afa7
Makefile.in contains updated files required
Matt Johnston <matt@ucc.asn.au>
parents:
diff
changeset
|
1479 |
1308 | 1480 p = buffer; |
1481 while (isbase64(*p)) { | |
1482 base64_bit[base64_chars++] = *p; | |
1483 if (base64_chars == 4) { | |
1484 unsigned char out[3]; | |
4
fe6bca95afa7
Makefile.in contains updated files required
Matt Johnston <matt@ucc.asn.au>
parents:
diff
changeset
|
1485 |
1308 | 1486 base64_chars = 0; |
1487 | |
1488 len = base64_decode_atom(base64_bit, out); | |
4
fe6bca95afa7
Makefile.in contains updated files required
Matt Johnston <matt@ucc.asn.au>
parents:
diff
changeset
|
1489 |
1308 | 1490 if (len <= 0) { |
1491 errmsg = "Invalid base64 encoding"; | |
1492 goto error; | |
1493 } | |
4
fe6bca95afa7
Makefile.in contains updated files required
Matt Johnston <matt@ucc.asn.au>
parents:
diff
changeset
|
1494 |
1308 | 1495 if (ret->keyblob_len + len > ret->keyblob_size) { |
1496 ret->keyblob_size = ret->keyblob_len + len + 256; | |
1497 ret->keyblob = sresize(ret->keyblob, ret->keyblob_size, | |
1498 unsigned char); | |
1499 } | |
4
fe6bca95afa7
Makefile.in contains updated files required
Matt Johnston <matt@ucc.asn.au>
parents:
diff
changeset
|
1500 |
1308 | 1501 memcpy(ret->keyblob + ret->keyblob_len, out, len); |
1502 ret->keyblob_len += len; | |
1503 } | |
1504 | |
1505 p++; | |
1506 } | |
1507 } | |
4
fe6bca95afa7
Makefile.in contains updated files required
Matt Johnston <matt@ucc.asn.au>
parents:
diff
changeset
|
1508 } |
fe6bca95afa7
Makefile.in contains updated files required
Matt Johnston <matt@ucc.asn.au>
parents:
diff
changeset
|
1509 |
1308 | 1510 if (ret->keyblob_len == 0 || !ret->keyblob) { |
1511 errmsg = "Key body not present"; | |
1512 goto error; | |
1513 } | |
1306
34e6127ef02e
merge fixes from PuTTY import.c
Matt Johnston <matt@ucc.asn.au>
parents:
1250
diff
changeset
|
1514 |
1308 | 1515 return ret; |
4
fe6bca95afa7
Makefile.in contains updated files required
Matt Johnston <matt@ucc.asn.au>
parents:
diff
changeset
|
1516 |
1308 | 1517 error: |
1518 if (ret) { | |
1519 if (ret->keyblob) { | |
1520 memset(ret->keyblob, 0, ret->keyblob_size); | |
4
fe6bca95afa7
Makefile.in contains updated files required
Matt Johnston <matt@ucc.asn.au>
parents:
diff
changeset
|
1521 m_free(ret->keyblob); |
1308 | 1522 } |
1523 memset(ret, 0, sizeof(*ret)); | |
4
fe6bca95afa7
Makefile.in contains updated files required
Matt Johnston <matt@ucc.asn.au>
parents:
diff
changeset
|
1524 m_free(ret); |
1308 | 1525 } |
1526 return NULL; | |
4
fe6bca95afa7
Makefile.in contains updated files required
Matt Johnston <matt@ucc.asn.au>
parents:
diff
changeset
|
1527 } |
fe6bca95afa7
Makefile.in contains updated files required
Matt Johnston <matt@ucc.asn.au>
parents:
diff
changeset
|
1528 |
fe6bca95afa7
Makefile.in contains updated files required
Matt Johnston <matt@ucc.asn.au>
parents:
diff
changeset
|
1529 int sshcom_encrypted(const char *filename, char **comment) |
fe6bca95afa7
Makefile.in contains updated files required
Matt Johnston <matt@ucc.asn.au>
parents:
diff
changeset
|
1530 { |
1308 | 1531 struct sshcom_key *key = load_sshcom_key(filename); |
1532 int pos, len, answer; | |
4
fe6bca95afa7
Makefile.in contains updated files required
Matt Johnston <matt@ucc.asn.au>
parents:
diff
changeset
|
1533 |
1308 | 1534 *comment = NULL; |
1535 if (!key) | |
1536 return 0; | |
4
fe6bca95afa7
Makefile.in contains updated files required
Matt Johnston <matt@ucc.asn.au>
parents:
diff
changeset
|
1537 |
1308 | 1538 /* |
1539 * Check magic number. | |
1540 */ | |
1541 if (GET_32BIT(key->keyblob) != 0x3f6ff9eb) | |
4
fe6bca95afa7
Makefile.in contains updated files required
Matt Johnston <matt@ucc.asn.au>
parents:
diff
changeset
|
1542 return 0; /* key is invalid */ |
fe6bca95afa7
Makefile.in contains updated files required
Matt Johnston <matt@ucc.asn.au>
parents:
diff
changeset
|
1543 |
1308 | 1544 /* |
1545 * Find the cipher-type string. | |
1546 */ | |
1547 answer = 0; | |
1548 pos = 8; | |
1549 if (key->keyblob_len < pos+4) | |
4
fe6bca95afa7
Makefile.in contains updated files required
Matt Johnston <matt@ucc.asn.au>
parents:
diff
changeset
|
1550 goto done; /* key is far too short */ |
1308 | 1551 len = toint(GET_32BIT(key->keyblob + pos)); |
1552 if (len < 0 || len > key->keyblob_len - pos - 4) | |
4
fe6bca95afa7
Makefile.in contains updated files required
Matt Johnston <matt@ucc.asn.au>
parents:
diff
changeset
|
1553 goto done; /* key is far too short */ |
1308 | 1554 pos += 4 + len; /* skip key type */ |
1555 len = toint(GET_32BIT(key->keyblob + pos)); /* find cipher-type length */ | |
1556 if (len < 0 || len > key->keyblob_len - pos - 4) | |
4
fe6bca95afa7
Makefile.in contains updated files required
Matt Johnston <matt@ucc.asn.au>
parents:
diff
changeset
|
1557 goto done; /* cipher type string is incomplete */ |
1308 | 1558 if (len != 4 || 0 != memcmp(key->keyblob + pos + 4, "none", 4)) |
1559 answer = 1; | |
4
fe6bca95afa7
Makefile.in contains updated files required
Matt Johnston <matt@ucc.asn.au>
parents:
diff
changeset
|
1560 |
1308 | 1561 done: |
1562 *comment = dupstr(key->comment); | |
1563 memset(key->keyblob, 0, key->keyblob_size); | |
4
fe6bca95afa7
Makefile.in contains updated files required
Matt Johnston <matt@ucc.asn.au>
parents:
diff
changeset
|
1564 m_free(key->keyblob); |
1308 | 1565 memset(key, 0, sizeof(*key)); |
4
fe6bca95afa7
Makefile.in contains updated files required
Matt Johnston <matt@ucc.asn.au>
parents:
diff
changeset
|
1566 m_free(key); |
1308 | 1567 return answer; |
4
fe6bca95afa7
Makefile.in contains updated files required
Matt Johnston <matt@ucc.asn.au>
parents:
diff
changeset
|
1568 } |
fe6bca95afa7
Makefile.in contains updated files required
Matt Johnston <matt@ucc.asn.au>
parents:
diff
changeset
|
1569 |
fe6bca95afa7
Makefile.in contains updated files required
Matt Johnston <matt@ucc.asn.au>
parents:
diff
changeset
|
1570 static int sshcom_read_mpint(void *data, int len, struct mpint_pos *ret) |
fe6bca95afa7
Makefile.in contains updated files required
Matt Johnston <matt@ucc.asn.au>
parents:
diff
changeset
|
1571 { |
1308 | 1572 unsigned bits, bytes; |
1573 unsigned char *d = (unsigned char *) data; | |
4
fe6bca95afa7
Makefile.in contains updated files required
Matt Johnston <matt@ucc.asn.au>
parents:
diff
changeset
|
1574 |
1308 | 1575 if (len < 4) |
1576 goto error; | |
1577 bits = GET_32BIT(d); | |
4
fe6bca95afa7
Makefile.in contains updated files required
Matt Johnston <matt@ucc.asn.au>
parents:
diff
changeset
|
1578 |
1308 | 1579 bytes = (bits + 7) / 8; |
1580 if (len < 4+bytes) | |
1581 goto error; | |
4
fe6bca95afa7
Makefile.in contains updated files required
Matt Johnston <matt@ucc.asn.au>
parents:
diff
changeset
|
1582 |
1308 | 1583 ret->start = d + 4; |
1584 ret->bytes = bytes; | |
1585 return bytes+4; | |
4
fe6bca95afa7
Makefile.in contains updated files required
Matt Johnston <matt@ucc.asn.au>
parents:
diff
changeset
|
1586 |
1308 | 1587 error: |
1588 ret->start = NULL; | |
1589 ret->bytes = -1; | |
4
fe6bca95afa7
Makefile.in contains updated files required
Matt Johnston <matt@ucc.asn.au>
parents:
diff
changeset
|
1590 return len; /* ensure further calls fail as well */ |
fe6bca95afa7
Makefile.in contains updated files required
Matt Johnston <matt@ucc.asn.au>
parents:
diff
changeset
|
1591 } |
fe6bca95afa7
Makefile.in contains updated files required
Matt Johnston <matt@ucc.asn.au>
parents:
diff
changeset
|
1592 |
fe6bca95afa7
Makefile.in contains updated files required
Matt Johnston <matt@ucc.asn.au>
parents:
diff
changeset
|
1593 static int sshcom_put_mpint(void *target, void *data, int len) |
fe6bca95afa7
Makefile.in contains updated files required
Matt Johnston <matt@ucc.asn.au>
parents:
diff
changeset
|
1594 { |
1308 | 1595 unsigned char *d = (unsigned char *)target; |
1596 unsigned char *i = (unsigned char *)data; | |
1597 int bits = len * 8 - 1; | |
4
fe6bca95afa7
Makefile.in contains updated files required
Matt Johnston <matt@ucc.asn.au>
parents:
diff
changeset
|
1598 |
1308 | 1599 while (bits > 0) { |
1600 if (*i & (1 << (bits & 7))) | |
1601 break; | |
1602 if (!(bits-- & 7)) | |
1603 i++, len--; | |
1604 } | |
4
fe6bca95afa7
Makefile.in contains updated files required
Matt Johnston <matt@ucc.asn.au>
parents:
diff
changeset
|
1605 |
1308 | 1606 PUT_32BIT(d, bits+1); |
1607 memcpy(d+4, i, len); | |
1608 return len+4; | |
4
fe6bca95afa7
Makefile.in contains updated files required
Matt Johnston <matt@ucc.asn.au>
parents:
diff
changeset
|
1609 } |
fe6bca95afa7
Makefile.in contains updated files required
Matt Johnston <matt@ucc.asn.au>
parents:
diff
changeset
|
1610 |
fe6bca95afa7
Makefile.in contains updated files required
Matt Johnston <matt@ucc.asn.au>
parents:
diff
changeset
|
1611 sign_key *sshcom_read(const char *filename, char *passphrase) |
fe6bca95afa7
Makefile.in contains updated files required
Matt Johnston <matt@ucc.asn.au>
parents:
diff
changeset
|
1612 { |
1308 | 1613 struct sshcom_key *key = load_sshcom_key(filename); |
1614 char *errmsg; | |
1615 int pos, len; | |
1616 const char prefix_rsa[] = "if-modn{sign{rsa"; | |
1617 const char prefix_dsa[] = "dl-modp{sign{dsa"; | |
1618 enum { RSA, DSA } type; | |
1619 int encrypted; | |
1620 char *ciphertext; | |
1621 int cipherlen; | |
1622 struct ssh2_userkey *ret = NULL, *retkey; | |
1623 const struct ssh_signkey *alg; | |
1624 unsigned char *blob = NULL; | |
1625 int blobsize = 0, publen, privlen; | |
1306
34e6127ef02e
merge fixes from PuTTY import.c
Matt Johnston <matt@ucc.asn.au>
parents:
1250
diff
changeset
|
1626 |
1308 | 1627 if (!key) |
1628 return NULL; | |
4
fe6bca95afa7
Makefile.in contains updated files required
Matt Johnston <matt@ucc.asn.au>
parents:
diff
changeset
|
1629 |
1308 | 1630 /* |
1631 * Check magic number. | |
1632 */ | |
1633 if (GET_32BIT(key->keyblob) != SSHCOM_MAGIC_NUMBER) { | |
1634 errmsg = "Key does not begin with magic number"; | |
1635 goto error; | |
1636 } | |
4
fe6bca95afa7
Makefile.in contains updated files required
Matt Johnston <matt@ucc.asn.au>
parents:
diff
changeset
|
1637 |
1308 | 1638 /* |
1639 * Determine the key type. | |
1640 */ | |
1641 pos = 8; | |
1642 if (key->keyblob_len < pos+4 || | |
1643 (len = GET_32BIT(key->keyblob + pos)) > key->keyblob_len - pos - 4) { | |
1644 errmsg = "Key blob does not contain a key type string"; | |
1645 goto error; | |
1646 } | |
1647 if (len > sizeof(prefix_rsa) - 1 && | |
1648 !memcmp(key->keyblob+pos+4, prefix_rsa, sizeof(prefix_rsa) - 1)) { | |
1649 type = RSA; | |
1650 } else if (len > sizeof(prefix_dsa) - 1 && | |
1651 !memcmp(key->keyblob+pos+4, prefix_dsa, sizeof(prefix_dsa) - 1)) { | |
1652 type = DSA; | |
1653 } else { | |
1654 errmsg = "Key is of unknown type"; | |
1655 goto error; | |
1656 } | |
1657 pos += 4+len; | |
1306
34e6127ef02e
merge fixes from PuTTY import.c
Matt Johnston <matt@ucc.asn.au>
parents:
1250
diff
changeset
|
1658 |
4
fe6bca95afa7
Makefile.in contains updated files required
Matt Johnston <matt@ucc.asn.au>
parents:
diff
changeset
|
1659 /* |
1308 | 1660 * Determine the cipher type. |
4
fe6bca95afa7
Makefile.in contains updated files required
Matt Johnston <matt@ucc.asn.au>
parents:
diff
changeset
|
1661 */ |
1308 | 1662 if (key->keyblob_len < pos+4 || |
1663 (len = GET_32BIT(key->keyblob + pos)) > key->keyblob_len - pos - 4) { | |
1664 errmsg = "Key blob does not contain a cipher type string"; | |
1665 goto error; | |
1666 } | |
1667 if (len == 4 && !memcmp(key->keyblob+pos+4, "none", 4)) | |
1668 encrypted = 0; | |
1669 else if (len == 8 && !memcmp(key->keyblob+pos+4, "3des-cbc", 8)) | |
1670 encrypted = 1; | |
1671 else { | |
1672 errmsg = "Key encryption is of unknown type"; | |
1673 goto error; | |
1674 } | |
1675 pos += 4+len; | |
1306
34e6127ef02e
merge fixes from PuTTY import.c
Matt Johnston <matt@ucc.asn.au>
parents:
1250
diff
changeset
|
1676 |
1308 | 1677 /* |
1678 * Get hold of the encrypted part of the key. | |
1679 */ | |
1680 if (key->keyblob_len < pos+4 || | |
1681 (len = GET_32BIT(key->keyblob + pos)) > key->keyblob_len - pos - 4) { | |
1682 errmsg = "Key blob does not contain actual key data"; | |
1683 goto error; | |
1684 } | |
1685 ciphertext = (char *)key->keyblob + pos + 4; | |
1686 cipherlen = len; | |
1687 if (cipherlen == 0) { | |
1688 errmsg = "Length of key data is zero"; | |
1689 goto error; | |
1690 } | |
4
fe6bca95afa7
Makefile.in contains updated files required
Matt Johnston <matt@ucc.asn.au>
parents:
diff
changeset
|
1691 |
fe6bca95afa7
Makefile.in contains updated files required
Matt Johnston <matt@ucc.asn.au>
parents:
diff
changeset
|
1692 /* |
1308 | 1693 * Decrypt it if necessary. |
4
fe6bca95afa7
Makefile.in contains updated files required
Matt Johnston <matt@ucc.asn.au>
parents:
diff
changeset
|
1694 */ |
1308 | 1695 if (encrypted) { |
1696 /* | |
1697 * Derive encryption key from passphrase and iv/salt: | |
1698 * | |
1699 * - let block A equal MD5(passphrase) | |
1700 * - let block B equal MD5(passphrase || A) | |
1701 * - block C would be MD5(passphrase || A || B) and so on | |
1702 * - encryption key is the first N bytes of A || B | |
1703 */ | |
1704 struct MD5Context md5c; | |
1705 unsigned char keybuf[32], iv[8]; | |
4
fe6bca95afa7
Makefile.in contains updated files required
Matt Johnston <matt@ucc.asn.au>
parents:
diff
changeset
|
1706 |
1308 | 1707 if (cipherlen % 8 != 0) { |
1708 errmsg = "Encrypted part of key is not a multiple of cipher block" | |
1709 " size"; | |
1710 goto error; | |
1711 } | |
1712 | |
1713 MD5Init(&md5c); | |
1714 MD5Update(&md5c, (unsigned char *)passphrase, strlen(passphrase)); | |
1715 MD5Final(keybuf, &md5c); | |
1716 | |
1717 MD5Init(&md5c); | |
1718 MD5Update(&md5c, (unsigned char *)passphrase, strlen(passphrase)); | |
1719 MD5Update(&md5c, keybuf, 16); | |
1720 MD5Final(keybuf+16, &md5c); | |
4
fe6bca95afa7
Makefile.in contains updated files required
Matt Johnston <matt@ucc.asn.au>
parents:
diff
changeset
|
1721 |
1308 | 1722 /* |
1723 * Now decrypt the key blob. | |
1724 */ | |
1725 memset(iv, 0, sizeof(iv)); | |
1726 des3_decrypt_pubkey_ossh(keybuf, iv, (unsigned char *)ciphertext, | |
1727 cipherlen); | |
1728 | |
1729 memset(&md5c, 0, sizeof(md5c)); | |
1730 memset(keybuf, 0, sizeof(keybuf)); | |
4
fe6bca95afa7
Makefile.in contains updated files required
Matt Johnston <matt@ucc.asn.au>
parents:
diff
changeset
|
1731 |
1308 | 1732 /* |
1733 * Hereafter we return WRONG_PASSPHRASE for any parsing | |
1734 * error. (But only if we've just tried to decrypt it! | |
1735 * Returning WRONG_PASSPHRASE for an unencrypted key is | |
1736 * automatic doom.) | |
1737 */ | |
1738 if (encrypted) | |
1739 ret = SSH2_WRONG_PASSPHRASE; | |
1740 } | |
1741 | |
1742 /* | |
1743 * Strip away the containing string to get to the real meat. | |
1744 */ | |
1745 len = toint(GET_32BIT(ciphertext)); | |
1746 if (len < 0 || len > cipherlen-4) { | |
1747 errmsg = "containing string was ill-formed"; | |
1748 goto error; | |
1749 } | |
1750 ciphertext += 4; | |
1751 cipherlen = len; | |
4
fe6bca95afa7
Makefile.in contains updated files required
Matt Johnston <matt@ucc.asn.au>
parents:
diff
changeset
|
1752 |
1308 | 1753 /* |
1754 * Now we break down into RSA versus DSA. In either case we'll | |
1755 * construct public and private blobs in our own format, and | |
1756 * end up feeding them to alg->createkey(). | |
1757 */ | |
1758 blobsize = cipherlen + 256; | |
1759 blob = snewn(blobsize, unsigned char); | |
1760 privlen = 0; | |
1761 if (type == RSA) { | |
1762 struct mpint_pos n, e, d, u, p, q; | |
1763 int pos = 0; | |
1764 pos += sshcom_read_mpint(ciphertext+pos, cipherlen-pos, &e); | |
1765 pos += sshcom_read_mpint(ciphertext+pos, cipherlen-pos, &d); | |
1766 pos += sshcom_read_mpint(ciphertext+pos, cipherlen-pos, &n); | |
1767 pos += sshcom_read_mpint(ciphertext+pos, cipherlen-pos, &u); | |
1768 pos += sshcom_read_mpint(ciphertext+pos, cipherlen-pos, &p); | |
1769 pos += sshcom_read_mpint(ciphertext+pos, cipherlen-pos, &q); | |
1770 if (!q.start) { | |
1771 errmsg = "key data did not contain six integers"; | |
1772 goto error; | |
1773 } | |
4
fe6bca95afa7
Makefile.in contains updated files required
Matt Johnston <matt@ucc.asn.au>
parents:
diff
changeset
|
1774 |
1308 | 1775 alg = &ssh_rsa; |
1776 pos = 0; | |
1777 pos += put_string(blob+pos, "ssh-rsa", 7); | |
1778 pos += put_mp(blob+pos, e.start, e.bytes); | |
1779 pos += put_mp(blob+pos, n.start, n.bytes); | |
1780 publen = pos; | |
1781 pos += put_string(blob+pos, d.start, d.bytes); | |
1782 pos += put_mp(blob+pos, q.start, q.bytes); | |
1783 pos += put_mp(blob+pos, p.start, p.bytes); | |
1784 pos += put_mp(blob+pos, u.start, u.bytes); | |
1785 privlen = pos - publen; | |
1786 } else if (type == DSA) { | |
1787 struct mpint_pos p, q, g, x, y; | |
1788 int pos = 4; | |
1789 if (GET_32BIT(ciphertext) != 0) { | |
1790 errmsg = "predefined DSA parameters not supported"; | |
1791 goto error; | |
1792 } | |
1793 pos += sshcom_read_mpint(ciphertext+pos, cipherlen-pos, &p); | |
1794 pos += sshcom_read_mpint(ciphertext+pos, cipherlen-pos, &g); | |
1795 pos += sshcom_read_mpint(ciphertext+pos, cipherlen-pos, &q); | |
1796 pos += sshcom_read_mpint(ciphertext+pos, cipherlen-pos, &y); | |
1797 pos += sshcom_read_mpint(ciphertext+pos, cipherlen-pos, &x); | |
1798 if (!x.start) { | |
1799 errmsg = "key data did not contain five integers"; | |
1800 goto error; | |
1801 } | |
4
fe6bca95afa7
Makefile.in contains updated files required
Matt Johnston <matt@ucc.asn.au>
parents:
diff
changeset
|
1802 |
1308 | 1803 alg = &ssh_dss; |
1804 pos = 0; | |
1805 pos += put_string(blob+pos, "ssh-dss", 7); | |
1806 pos += put_mp(blob+pos, p.start, p.bytes); | |
1807 pos += put_mp(blob+pos, q.start, q.bytes); | |
1808 pos += put_mp(blob+pos, g.start, g.bytes); | |
1809 pos += put_mp(blob+pos, y.start, y.bytes); | |
1810 publen = pos; | |
1811 pos += put_mp(blob+pos, x.start, x.bytes); | |
1812 privlen = pos - publen; | |
1813 } else | |
1814 return NULL; | |
1815 | |
241
c5d3ef11155f
* use own assertions which should get logged properly
Matt Johnston <matt@ucc.asn.au>
parents:
87
diff
changeset
|
1816 dropbear_assert(privlen > 0); /* should have bombed by now if not */ |
4
fe6bca95afa7
Makefile.in contains updated files required
Matt Johnston <matt@ucc.asn.au>
parents:
diff
changeset
|
1817 |
1308 | 1818 retkey = snew(struct ssh2_userkey); |
1819 retkey->alg = alg; | |
1820 retkey->data = alg->createkey(blob, publen, blob+publen, privlen); | |
1821 if (!retkey->data) { | |
4
fe6bca95afa7
Makefile.in contains updated files required
Matt Johnston <matt@ucc.asn.au>
parents:
diff
changeset
|
1822 m_free(retkey); |
1308 | 1823 errmsg = "unable to create key data structure"; |
1824 goto error; | |
1825 } | |
1826 retkey->comment = dupstr(key->comment); | |
4
fe6bca95afa7
Makefile.in contains updated files required
Matt Johnston <matt@ucc.asn.au>
parents:
diff
changeset
|
1827 |
1308 | 1828 errmsg = NULL; /* no error */ |
1829 ret = retkey; | |
1830 | |
1831 error: | |
1832 if (blob) { | |
1833 memset(blob, 0, blobsize); | |
4
fe6bca95afa7
Makefile.in contains updated files required
Matt Johnston <matt@ucc.asn.au>
parents:
diff
changeset
|
1834 m_free(blob); |
1308 | 1835 } |
1836 memset(key->keyblob, 0, key->keyblob_size); | |
4
fe6bca95afa7
Makefile.in contains updated files required
Matt Johnston <matt@ucc.asn.au>
parents:
diff
changeset
|
1837 m_free(key->keyblob); |
1308 | 1838 memset(key, 0, sizeof(*key)); |
4
fe6bca95afa7
Makefile.in contains updated files required
Matt Johnston <matt@ucc.asn.au>
parents:
diff
changeset
|
1839 m_free(key); |
1308 | 1840 return ret; |
4
fe6bca95afa7
Makefile.in contains updated files required
Matt Johnston <matt@ucc.asn.au>
parents:
diff
changeset
|
1841 } |
fe6bca95afa7
Makefile.in contains updated files required
Matt Johnston <matt@ucc.asn.au>
parents:
diff
changeset
|
1842 |
fe6bca95afa7
Makefile.in contains updated files required
Matt Johnston <matt@ucc.asn.au>
parents:
diff
changeset
|
1843 int sshcom_write(const char *filename, sign_key *key, |
1308 | 1844 char *passphrase) |
4
fe6bca95afa7
Makefile.in contains updated files required
Matt Johnston <matt@ucc.asn.au>
parents:
diff
changeset
|
1845 { |
1308 | 1846 unsigned char *pubblob, *privblob; |
1847 int publen, privlen; | |
1848 unsigned char *outblob; | |
1849 int outlen; | |
1850 struct mpint_pos numbers[6]; | |
1851 int nnumbers, initial_zero, pos, lenpos, i; | |
1852 char *type; | |
1853 char *ciphertext; | |
1854 int cipherlen; | |
1855 int ret = 0; | |
1856 FILE *fp; | |
4
fe6bca95afa7
Makefile.in contains updated files required
Matt Johnston <matt@ucc.asn.au>
parents:
diff
changeset
|
1857 |
1308 | 1858 /* |
1859 * Fetch the key blobs. | |
1860 */ | |
1861 pubblob = key->alg->public_blob(key->data, &publen); | |
1862 privblob = key->alg->private_blob(key->data, &privlen); | |
1863 outblob = NULL; | |
4
fe6bca95afa7
Makefile.in contains updated files required
Matt Johnston <matt@ucc.asn.au>
parents:
diff
changeset
|
1864 |
1308 | 1865 /* |
1866 * Find the sequence of integers to be encoded into the OpenSSH | |
1867 * key blob, and also decide on the header line. | |
1868 */ | |
1869 if (key->alg == &ssh_rsa) { | |
1870 int pos; | |
1871 struct mpint_pos n, e, d, p, q, iqmp; | |
4
fe6bca95afa7
Makefile.in contains updated files required
Matt Johnston <matt@ucc.asn.au>
parents:
diff
changeset
|
1872 |
1308 | 1873 pos = 4 + GET_32BIT(pubblob); |
1874 pos += ssh2_read_mpint(pubblob+pos, publen-pos, &e); | |
1875 pos += ssh2_read_mpint(pubblob+pos, publen-pos, &n); | |
1876 pos = 0; | |
1877 pos += ssh2_read_mpint(privblob+pos, privlen-pos, &d); | |
1878 pos += ssh2_read_mpint(privblob+pos, privlen-pos, &p); | |
1879 pos += ssh2_read_mpint(privblob+pos, privlen-pos, &q); | |
1880 pos += ssh2_read_mpint(privblob+pos, privlen-pos, &iqmp); | |
4
fe6bca95afa7
Makefile.in contains updated files required
Matt Johnston <matt@ucc.asn.au>
parents:
diff
changeset
|
1881 |
241
c5d3ef11155f
* use own assertions which should get logged properly
Matt Johnston <matt@ucc.asn.au>
parents:
87
diff
changeset
|
1882 dropbear_assert(e.start && iqmp.start); /* can't go wrong */ |
4
fe6bca95afa7
Makefile.in contains updated files required
Matt Johnston <matt@ucc.asn.au>
parents:
diff
changeset
|
1883 |
1308 | 1884 numbers[0] = e; |
1885 numbers[1] = d; | |
1886 numbers[2] = n; | |
1887 numbers[3] = iqmp; | |
1888 numbers[4] = q; | |
1889 numbers[5] = p; | |
4
fe6bca95afa7
Makefile.in contains updated files required
Matt Johnston <matt@ucc.asn.au>
parents:
diff
changeset
|
1890 |
1308 | 1891 nnumbers = 6; |
1892 initial_zero = 0; | |
1893 type = "if-modn{sign{rsa-pkcs1-sha1},encrypt{rsa-pkcs1v2-oaep}}"; | |
1894 } else if (key->alg == &ssh_dss) { | |
1895 int pos; | |
1896 struct mpint_pos p, q, g, y, x; | |
1897 | |
1898 pos = 4 + GET_32BIT(pubblob); | |
1899 pos += ssh2_read_mpint(pubblob+pos, publen-pos, &p); | |
1900 pos += ssh2_read_mpint(pubblob+pos, publen-pos, &q); | |
1901 pos += ssh2_read_mpint(pubblob+pos, publen-pos, &g); | |
1902 pos += ssh2_read_mpint(pubblob+pos, publen-pos, &y); | |
1903 pos = 0; | |
1904 pos += ssh2_read_mpint(privblob+pos, privlen-pos, &x); | |
4
fe6bca95afa7
Makefile.in contains updated files required
Matt Johnston <matt@ucc.asn.au>
parents:
diff
changeset
|
1905 |
241
c5d3ef11155f
* use own assertions which should get logged properly
Matt Johnston <matt@ucc.asn.au>
parents:
87
diff
changeset
|
1906 dropbear_assert(y.start && x.start); /* can't go wrong */ |
1308 | 1907 |
1908 numbers[0] = p; | |
1909 numbers[1] = g; | |
1910 numbers[2] = q; | |
1911 numbers[3] = y; | |
1912 numbers[4] = x; | |
4
fe6bca95afa7
Makefile.in contains updated files required
Matt Johnston <matt@ucc.asn.au>
parents:
diff
changeset
|
1913 |
1308 | 1914 nnumbers = 5; |
1915 initial_zero = 1; | |
1916 type = "dl-modp{sign{dsa-nist-sha1},dh{plain}}"; | |
1917 } else { | |
241
c5d3ef11155f
* use own assertions which should get logged properly
Matt Johnston <matt@ucc.asn.au>
parents:
87
diff
changeset
|
1918 dropbear_assert(0); /* zoinks! */ |
1308 | 1919 } |
4
fe6bca95afa7
Makefile.in contains updated files required
Matt Johnston <matt@ucc.asn.au>
parents:
diff
changeset
|
1920 |
fe6bca95afa7
Makefile.in contains updated files required
Matt Johnston <matt@ucc.asn.au>
parents:
diff
changeset
|
1921 /* |
1308 | 1922 * Total size of key blob will be somewhere under 512 plus |
1923 * combined length of integers. We'll calculate the more | |
1924 * precise size as we construct the blob. | |
4
fe6bca95afa7
Makefile.in contains updated files required
Matt Johnston <matt@ucc.asn.au>
parents:
diff
changeset
|
1925 */ |
1308 | 1926 outlen = 512; |
1927 for (i = 0; i < nnumbers; i++) | |
1928 outlen += 4 + numbers[i].bytes; | |
1929 outblob = snewn(outlen, unsigned char); | |
4
fe6bca95afa7
Makefile.in contains updated files required
Matt Johnston <matt@ucc.asn.au>
parents:
diff
changeset
|
1930 |
fe6bca95afa7
Makefile.in contains updated files required
Matt Johnston <matt@ucc.asn.au>
parents:
diff
changeset
|
1931 /* |
1308 | 1932 * Create the unencrypted key blob. |
4
fe6bca95afa7
Makefile.in contains updated files required
Matt Johnston <matt@ucc.asn.au>
parents:
diff
changeset
|
1933 */ |
1308 | 1934 pos = 0; |
1935 PUT_32BIT(outblob+pos, SSHCOM_MAGIC_NUMBER); pos += 4; | |
4
fe6bca95afa7
Makefile.in contains updated files required
Matt Johnston <matt@ucc.asn.au>
parents:
diff
changeset
|
1936 pos += 4; /* length field, fill in later */ |
1308 | 1937 pos += put_string(outblob+pos, type, strlen(type)); |
1938 { | |
1939 char *ciphertype = passphrase ? "3des-cbc" : "none"; | |
1940 pos += put_string(outblob+pos, ciphertype, strlen(ciphertype)); | |
1941 } | |
4
fe6bca95afa7
Makefile.in contains updated files required
Matt Johnston <matt@ucc.asn.au>
parents:
diff
changeset
|
1942 lenpos = pos; /* remember this position */ |
fe6bca95afa7
Makefile.in contains updated files required
Matt Johnston <matt@ucc.asn.au>
parents:
diff
changeset
|
1943 pos += 4; /* encrypted-blob size */ |
fe6bca95afa7
Makefile.in contains updated files required
Matt Johnston <matt@ucc.asn.au>
parents:
diff
changeset
|
1944 pos += 4; /* encrypted-payload size */ |
1308 | 1945 if (initial_zero) { |
1946 PUT_32BIT(outblob+pos, 0); | |
1947 pos += 4; | |
1948 } | |
1949 for (i = 0; i < nnumbers; i++) | |
1950 pos += sshcom_put_mpint(outblob+pos, | |
1951 numbers[i].start, numbers[i].bytes); | |
1952 /* Now wrap up the encrypted payload. */ | |
1953 PUT_32BIT(outblob+lenpos+4, pos - (lenpos+8)); | |
1954 /* Pad encrypted blob to a multiple of cipher block size. */ | |
1955 if (passphrase) { | |
1956 int padding = -(pos - (lenpos+4)) & 7; | |
1957 while (padding--) | |
1958 outblob[pos++] = random_byte(); | |
1959 } | |
1960 ciphertext = (char *)outblob+lenpos+4; | |
1961 cipherlen = pos - (lenpos+4); | |
241
c5d3ef11155f
* use own assertions which should get logged properly
Matt Johnston <matt@ucc.asn.au>
parents:
87
diff
changeset
|
1962 dropbear_assert(!passphrase || cipherlen % 8 == 0); |
1308 | 1963 /* Wrap up the encrypted blob string. */ |
1964 PUT_32BIT(outblob+lenpos, cipherlen); | |
1965 /* And finally fill in the total length field. */ | |
1966 PUT_32BIT(outblob+4, pos); | |
1306
34e6127ef02e
merge fixes from PuTTY import.c
Matt Johnston <matt@ucc.asn.au>
parents:
1250
diff
changeset
|
1967 |
241
c5d3ef11155f
* use own assertions which should get logged properly
Matt Johnston <matt@ucc.asn.au>
parents:
87
diff
changeset
|
1968 dropbear_assert(pos < outlen); |
1308 | 1969 |
1970 /* | |
1971 * Encrypt the key. | |
1972 */ | |
1973 if (passphrase) { | |
1974 /* | |
1975 * Derive encryption key from passphrase and iv/salt: | |
1976 * | |
1977 * - let block A equal MD5(passphrase) | |
1978 * - let block B equal MD5(passphrase || A) | |
1979 * - block C would be MD5(passphrase || A || B) and so on | |
1980 * - encryption key is the first N bytes of A || B | |
1981 */ | |
1982 struct MD5Context md5c; | |
1983 unsigned char keybuf[32], iv[8]; | |
1984 | |
1985 MD5Init(&md5c); | |
1986 MD5Update(&md5c, (unsigned char *)passphrase, strlen(passphrase)); | |
1987 MD5Final(keybuf, &md5c); | |
4
fe6bca95afa7
Makefile.in contains updated files required
Matt Johnston <matt@ucc.asn.au>
parents:
diff
changeset
|
1988 |
1308 | 1989 MD5Init(&md5c); |
1990 MD5Update(&md5c, (unsigned char *)passphrase, strlen(passphrase)); | |
1991 MD5Update(&md5c, keybuf, 16); | |
1992 MD5Final(keybuf+16, &md5c); | |
1993 | |
1994 /* | |
1995 * Now decrypt the key blob. | |
1996 */ | |
1997 memset(iv, 0, sizeof(iv)); | |
1998 des3_encrypt_pubkey_ossh(keybuf, iv, (unsigned char *)ciphertext, | |
1999 cipherlen); | |
2000 | |
2001 memset(&md5c, 0, sizeof(md5c)); | |
2002 memset(keybuf, 0, sizeof(keybuf)); | |
4
fe6bca95afa7
Makefile.in contains updated files required
Matt Johnston <matt@ucc.asn.au>
parents:
diff
changeset
|
2003 } |
1306
34e6127ef02e
merge fixes from PuTTY import.c
Matt Johnston <matt@ucc.asn.au>
parents:
1250
diff
changeset
|
2004 |
1308 | 2005 /* |
2006 * And save it. We'll use Unix line endings just in case it's | |
2007 * subsequently transferred in binary mode. | |
2008 */ | |
4
fe6bca95afa7
Makefile.in contains updated files required
Matt Johnston <matt@ucc.asn.au>
parents:
diff
changeset
|
2009 fp = fopen(filename, "wb"); /* ensure Unix line endings */ |
1308 | 2010 if (!fp) |
2011 goto error; | |
2012 fputs("---- BEGIN SSH2 ENCRYPTED PRIVATE KEY ----\n", fp); | |
2013 fprintf(fp, "Comment: \""); | |
2014 /* | |
2015 * Comment header is broken with backslash-newline if it goes | |
2016 * over 70 chars. Although it's surrounded by quotes, it | |
2017 * _doesn't_ escape backslashes or quotes within the string. | |
2018 * Don't ask me, I didn't design it. | |
2019 */ | |
2020 { | |
4
fe6bca95afa7
Makefile.in contains updated files required
Matt Johnston <matt@ucc.asn.au>
parents:
diff
changeset
|
2021 int slen = 60; /* starts at 60 due to "Comment: " */ |
1308 | 2022 char *c = key->comment; |
2023 while ((int)strlen(c) > slen) { | |
2024 fprintf(fp, "%.*s\\\n", slen, c); | |
2025 c += slen; | |
4
fe6bca95afa7
Makefile.in contains updated files required
Matt Johnston <matt@ucc.asn.au>
parents:
diff
changeset
|
2026 slen = 70; /* allow 70 chars on subsequent lines */ |
1308 | 2027 } |
2028 fprintf(fp, "%s\"\n", c); | |
2029 } | |
4
fe6bca95afa7
Makefile.in contains updated files required
Matt Johnston <matt@ucc.asn.au>
parents:
diff
changeset
|
2030 base64_encode_fp(fp, outblob, pos, 70); |
1308 | 2031 fputs("---- END SSH2 ENCRYPTED PRIVATE KEY ----\n", fp); |
2032 fclose(fp); | |
2033 ret = 1; | |
2034 | |
2035 error: | |
2036 if (outblob) { | |
2037 memset(outblob, 0, outlen); | |
4
fe6bca95afa7
Makefile.in contains updated files required
Matt Johnston <matt@ucc.asn.au>
parents:
diff
changeset
|
2038 m_free(outblob); |
1308 | 2039 } |
2040 if (privblob) { | |
2041 memset(privblob, 0, privlen); | |
4
fe6bca95afa7
Makefile.in contains updated files required
Matt Johnston <matt@ucc.asn.au>
parents:
diff
changeset
|
2042 m_free(privblob); |
1308 | 2043 } |
2044 if (pubblob) { | |
2045 memset(pubblob, 0, publen); | |
4
fe6bca95afa7
Makefile.in contains updated files required
Matt Johnston <matt@ucc.asn.au>
parents:
diff
changeset
|
2046 m_free(pubblob); |
1308 | 2047 } |
2048 return ret; | |
4
fe6bca95afa7
Makefile.in contains updated files required
Matt Johnston <matt@ucc.asn.au>
parents:
diff
changeset
|
2049 } |
fe6bca95afa7
Makefile.in contains updated files required
Matt Johnston <matt@ucc.asn.au>
parents:
diff
changeset
|
2050 #endif /* ssh.com stuff disabled */ |
1306
34e6127ef02e
merge fixes from PuTTY import.c
Matt Johnston <matt@ucc.asn.au>
parents:
1250
diff
changeset
|
2051 |
34e6127ef02e
merge fixes from PuTTY import.c
Matt Johnston <matt@ucc.asn.au>
parents:
1250
diff
changeset
|
2052 /* From PuTTY misc.c */ |
34e6127ef02e
merge fixes from PuTTY import.c
Matt Johnston <matt@ucc.asn.au>
parents:
1250
diff
changeset
|
2053 static int toint(unsigned u) |
34e6127ef02e
merge fixes from PuTTY import.c
Matt Johnston <matt@ucc.asn.au>
parents:
1250
diff
changeset
|
2054 { |
1308 | 2055 /* |
2056 * Convert an unsigned to an int, without running into the | |
2057 * undefined behaviour which happens by the strict C standard if | |
2058 * the value overflows. You'd hope that sensible compilers would | |
2059 * do the sensible thing in response to a cast, but actually I | |
2060 * don't trust modern compilers not to do silly things like | |
2061 * assuming that _obviously_ you wouldn't have caused an overflow | |
2062 * and so they can elide an 'if (i < 0)' test immediately after | |
2063 * the cast. | |
2064 * | |
2065 * Sensible compilers ought of course to optimise this entire | |
2066 * function into 'just return the input value'! | |
2067 */ | |
2068 if (u <= (unsigned)INT_MAX) | |
2069 return (int)u; | |
2070 else if (u >= (unsigned)INT_MIN) /* wrap in cast _to_ unsigned is OK */ | |
2071 return INT_MIN + (int)(u - (unsigned)INT_MIN); | |
2072 else | |
2073 return INT_MIN; /* fallback; should never occur on binary machines */ | |
1306
34e6127ef02e
merge fixes from PuTTY import.c
Matt Johnston <matt@ucc.asn.au>
parents:
1250
diff
changeset
|
2074 } |