2 * Dropbear - a SSH2 server
4 * Copyright (c) 2002,2003 Matt Johnston
7 * Permission is hereby granted, free of charge, to any person obtaining a copy
8 * of this software and associated documentation files (the "Software"), to deal
9 * in the Software without restriction, including without limitation the rights
10 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
11 * copies of the Software, and to permit persons to whom the Software is
12 * furnished to do so, subject to the following conditions:
14 * The above copyright notice and this permission notice shall be included in
15 * all copies or substantial portions of the Software.
17 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
18 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
19 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
20 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
21 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
22 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
31 /* malloc a new sign_key and set the dss and rsa keys to NULL */
32 sign_key * new_sign_key() {
36 ret = (sign_key*)m_malloc(sizeof(sign_key));
47 /* returns DROPBEAR_SUCCESS on success, DROPBEAR_FAILURE on fail */
48 int buf_get_pub_key(buffer *buf, sign_key *key, int type) {
53 ident = buf_getstring(buf, &len);
56 if (memcmp(ident, SSH_SIGNKEY_DSS, len) == 0
57 && (type == DROPBEAR_SIGNKEY_ANY || type == DROPBEAR_SIGNKEY_DSS)) {
59 buf_setpos(buf, buf->pos - len - 4);
60 dss_key_free(key->dsskey);
61 key->dsskey = (dss_key*)m_malloc(sizeof(dss_key));
62 return buf_get_dss_pub_key(buf, key->dsskey);
66 if (memcmp(ident, SSH_SIGNKEY_RSA, len) == 0
67 && (type == DROPBEAR_SIGNKEY_ANY || type == DROPBEAR_SIGNKEY_RSA)) {
69 buf_setpos(buf, buf->pos - len - 4);
70 rsa_key_free(key->rsakey);
71 key->rsakey = (rsa_key*)m_malloc(sizeof(rsa_key));
72 return buf_get_rsa_pub_key(buf, key->rsakey);
78 return DROPBEAR_FAILURE;
82 /* returns DROPBEAR_SUCCESS or DROPBEAR_FAILURE */
83 int buf_get_priv_key(buffer *buf, sign_key *key, int type) {
89 TRACE(("enter buf_get_priv_key"));
90 ident = buf_getstring(buf, &len);
93 if (memcmp(ident, SSH_SIGNKEY_DSS, len) == 0
94 && (type == DROPBEAR_SIGNKEY_ANY || type == DROPBEAR_SIGNKEY_DSS)) {
96 buf_setpos(buf, buf->pos - len - 4);
97 dss_key_free(key->dsskey);
98 key->dsskey = (dss_key*)m_malloc(sizeof(dss_key));
99 ret = buf_get_dss_priv_key(buf, key->dsskey);
100 if (ret == DROPBEAR_FAILURE) {
103 TRACE(("leave buf_get_priv_key: done get dss"));
108 if (memcmp(ident, SSH_SIGNKEY_RSA, len) == 0
109 && (type == DROPBEAR_SIGNKEY_ANY || type == DROPBEAR_SIGNKEY_RSA)) {
111 buf_setpos(buf, buf->pos - len - 4);
112 rsa_key_free(key->rsakey);
113 key->rsakey = (rsa_key*)m_malloc(sizeof(rsa_key));
114 ret = buf_get_rsa_priv_key(buf, key->rsakey);
115 if (ret == DROPBEAR_FAILURE) {
118 TRACE(("leave buf_get_priv_key: done get rsa"));
125 TRACE(("leave buf_get_priv_key"));
126 return DROPBEAR_FAILURE;
130 /* type is either DROPBEAR_SIGNKEY_DSS or DROPBEAR_SIGNKEY_RSA */
131 void buf_put_pub_key(buffer* buf, sign_key *key, int type) {
135 TRACE(("enter buf_put_pub_key"));
136 pubkeys = buf_new(1000);
139 if (type == DROPBEAR_SIGNKEY_DSS) {
140 buf_put_dss_pub_key(pubkeys, key->dsskey);
144 if (type == DROPBEAR_SIGNKEY_RSA) {
145 buf_put_rsa_pub_key(pubkeys, key->rsakey);
148 if (pubkeys->len == 0) {
149 dropbear_exit("bad key types in buf_put_pub_key");
152 buf_setpos(pubkeys, 0);
153 buf_putstring(buf, buf_getptr(pubkeys, pubkeys->len),
157 TRACE(("leave buf_put_pub_key"));
160 /* type is either DROPBEAR_SIGNKEY_DSS or DROPBEAR_SIGNKEY_RSA */
161 void buf_put_priv_key(buffer* buf, sign_key *key, int type) {
163 TRACE(("enter buf_put_priv_key"));
164 TRACE(("type is %d\n", type));
167 if (type == DROPBEAR_SIGNKEY_DSS) {
168 buf_put_dss_priv_key(buf, key->dsskey);
169 TRACE(("leave buf_put_priv_key: dss done"));
174 if (type == DROPBEAR_SIGNKEY_RSA) {
175 buf_put_rsa_priv_key(buf, key->rsakey);
176 TRACE(("leave buf_put_priv_key: rsa done"));
180 dropbear_exit("bad key types in put pub key");
183 void sign_key_free(sign_key *key) {
185 TRACE(("enter sign_key_free"));
188 dss_key_free(key->dsskey);
191 rsa_key_free(key->rsakey);
195 TRACE(("leave sign_key_free"));
198 void buf_put_sign(buffer* buf, sign_key *key, int type,
199 const unsigned char *data, unsigned int len) {
203 sigblob = buf_new(1000);
206 if (type == DROPBEAR_SIGNKEY_DSS) {
207 buf_put_dss_sign(sigblob, key->dsskey, data, len);
211 if (type == DROPBEAR_SIGNKEY_RSA) {
212 buf_put_rsa_sign(sigblob, key->rsakey, data, len);
215 if (sigblob->len == 0) {
216 dropbear_exit("non-matching signing type");
219 buf_setpos(sigblob, 0);
220 buf_putstring(buf, buf_getptr(sigblob, sigblob->len),
227 #ifdef DROPBEAR_SIGNKEY_VERIFY
228 /* Return DROPBEAR_SUCCESS or DROPBEAR_FAILURE.
229 * If FAILURE is returned, the position of
230 * buf is undefined. If SUCCESS is returned, buf will be positioned after the
232 int buf_verify(buffer * buf, sign_key *key, const unsigned char *data,
235 unsigned int bloblen;
236 unsigned char * ident = NULL;
237 unsigned int identlen = 0;
239 bloblen = buf_getint(buf);
240 ident = buf_getstring(buf, &identlen);
243 if (bloblen == DSS_SIGNATURE_SIZE &&
244 memcmp(ident, SSH_SIGNKEY_DSS, identlen) == 0) {
246 return buf_dss_verify(buf, key->dsskey, data, len);
251 if (memcmp(ident, SSH_SIGNKEY_RSA, identlen) == 0) {
253 return buf_rsa_verify(buf, key->rsakey, data, len);
258 dropbear_exit("non-matching signing type");
259 return DROPBEAR_FAILURE;
261 #endif /* DROPBEAR_SIGNKEY_VERIFY */