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