comparison rsa.c @ 370:9a789fc03f40

Make sure that we clean up key parts if we fail during reading a rsa key (from Klocwork)
author Matt Johnston <matt@ucc.asn.au>
date Thu, 02 Nov 2006 16:10:18 +0000
parents 3cea9d789cca
children a124aff0cbf1
comparison
equal deleted inserted replaced
369:8eaa6e3ca6eb 370:9a789fc03f40
46 * The key will have the same format as buf_put_rsa_key. 46 * The key will have the same format as buf_put_rsa_key.
47 * These should be freed with rsa_key_free. 47 * These should be freed with rsa_key_free.
48 * Returns DROPBEAR_SUCCESS or DROPBEAR_FAILURE */ 48 * Returns DROPBEAR_SUCCESS or DROPBEAR_FAILURE */
49 int buf_get_rsa_pub_key(buffer* buf, rsa_key *key) { 49 int buf_get_rsa_pub_key(buffer* buf, rsa_key *key) {
50 50
51 int ret = DROPBEAR_FAILURE;
51 TRACE(("enter buf_get_rsa_pub_key")) 52 TRACE(("enter buf_get_rsa_pub_key"))
52 dropbear_assert(key != NULL); 53 dropbear_assert(key != NULL);
53 key->e = m_malloc(sizeof(mp_int)); 54 key->e = m_malloc(sizeof(mp_int));
54 key->n = m_malloc(sizeof(mp_int)); 55 key->n = m_malloc(sizeof(mp_int));
55 m_mp_init_multi(key->e, key->n, NULL); 56 m_mp_init_multi(key->e, key->n, NULL);
60 buf_incrpos(buf, 4+SSH_SIGNKEY_RSA_LEN); /* int + "ssh-rsa" */ 61 buf_incrpos(buf, 4+SSH_SIGNKEY_RSA_LEN); /* int + "ssh-rsa" */
61 62
62 if (buf_getmpint(buf, key->e) == DROPBEAR_FAILURE 63 if (buf_getmpint(buf, key->e) == DROPBEAR_FAILURE
63 || buf_getmpint(buf, key->n) == DROPBEAR_FAILURE) { 64 || buf_getmpint(buf, key->n) == DROPBEAR_FAILURE) {
64 TRACE(("leave buf_get_rsa_pub_key: failure")) 65 TRACE(("leave buf_get_rsa_pub_key: failure"))
65 return DROPBEAR_FAILURE; 66 goto out;
66 } 67 }
67 68
68 if (mp_count_bits(key->n) < MIN_RSA_KEYLEN) { 69 if (mp_count_bits(key->n) < MIN_RSA_KEYLEN) {
69 dropbear_log(LOG_WARNING, "rsa key too short"); 70 dropbear_log(LOG_WARNING, "rsa key too short");
70 return DROPBEAR_FAILURE; 71 goto out;
71 } 72 }
72 73
73 TRACE(("leave buf_get_rsa_pub_key: success")) 74 TRACE(("leave buf_get_rsa_pub_key: success"))
74 return DROPBEAR_SUCCESS; 75 ret = DROPBEAR_SUCCESS;
75 76 out:
76 } 77 if (ret == DROPBEAR_FAILURE) {
77 78 m_free(key->e);
78 /* Same as buf_get_rsa_pub_key, but reads a private "x" key at the end. 79 m_free(key->n);
80 }
81 return ret;
82 }
83
84 /* Same as buf_get_rsa_pub_key, but reads private bits at the end.
79 * Loads a private rsa key from a buffer 85 * Loads a private rsa key from a buffer
80 * Returns DROPBEAR_SUCCESS or DROPBEAR_FAILURE */ 86 * Returns DROPBEAR_SUCCESS or DROPBEAR_FAILURE */
81 int buf_get_rsa_priv_key(buffer* buf, rsa_key *key) { 87 int buf_get_rsa_priv_key(buffer* buf, rsa_key *key) {
82 88 int ret = DROPBEAR_FAILURE;
83 dropbear_assert(key != NULL);
84 89
85 TRACE(("enter buf_get_rsa_priv_key")) 90 TRACE(("enter buf_get_rsa_priv_key"))
91 dropbear_assert(key != NULL);
86 92
87 if (buf_get_rsa_pub_key(buf, key) == DROPBEAR_FAILURE) { 93 if (buf_get_rsa_pub_key(buf, key) == DROPBEAR_FAILURE) {
88 TRACE(("leave buf_get_rsa_priv_key: pub: ret == DROPBEAR_FAILURE")) 94 TRACE(("leave buf_get_rsa_priv_key: pub: ret == DROPBEAR_FAILURE"))
89 return DROPBEAR_FAILURE; 95 return DROPBEAR_FAILURE;
90 } 96 }
97
98 key->d = NULL;
99 key->p = NULL;
100 key->q = NULL;
91 101
92 key->d = m_malloc(sizeof(mp_int)); 102 key->d = m_malloc(sizeof(mp_int));
93 m_mp_init(key->d); 103 m_mp_init(key->d);
94 if (buf_getmpint(buf, key->d) == DROPBEAR_FAILURE) { 104 if (buf_getmpint(buf, key->d) == DROPBEAR_FAILURE) {
95 TRACE(("leave buf_get_rsa_priv_key: d: ret == DROPBEAR_FAILURE")) 105 TRACE(("leave buf_get_rsa_priv_key: d: ret == DROPBEAR_FAILURE"))
96 return DROPBEAR_FAILURE; 106 goto out;
97 } 107 }
98 108
99 /* old Dropbear private keys didn't keep p and q, so we will ignore them*/
100 if (buf->pos == buf->len) { 109 if (buf->pos == buf->len) {
101 key->p = NULL; 110 /* old Dropbear private keys didn't keep p and q, so we will ignore them*/
102 key->q = NULL;
103 } else { 111 } else {
104 key->p = m_malloc(sizeof(mp_int)); 112 key->p = m_malloc(sizeof(mp_int));
105 key->q = m_malloc(sizeof(mp_int)); 113 key->q = m_malloc(sizeof(mp_int));
106 m_mp_init_multi(key->p, key->q, NULL); 114 m_mp_init_multi(key->p, key->q, NULL);
107 115
108 if (buf_getmpint(buf, key->p) == DROPBEAR_FAILURE) { 116 if (buf_getmpint(buf, key->p) == DROPBEAR_FAILURE) {
109 TRACE(("leave buf_get_rsa_priv_key: p: ret == DROPBEAR_FAILURE")) 117 TRACE(("leave buf_get_rsa_priv_key: p: ret == DROPBEAR_FAILURE"))
110 return DROPBEAR_FAILURE; 118 goto out;
111 } 119 }
112 120
113 if (buf_getmpint(buf, key->q) == DROPBEAR_FAILURE) { 121 if (buf_getmpint(buf, key->q) == DROPBEAR_FAILURE) {
114 TRACE(("leave buf_get_rsa_priv_key: q: ret == DROPBEAR_FAILURE")) 122 TRACE(("leave buf_get_rsa_priv_key: q: ret == DROPBEAR_FAILURE"))
115 return DROPBEAR_FAILURE; 123 goto out;
116 } 124 }
117 } 125 }
118 126
127 ret = DROPBEAR_SUCCESS;
128 out:
129 if (ret == DROPBEAR_FAILURE) {
130 m_free(key->d);
131 m_free(key->p);
132 m_free(key->q);
133 }
119 TRACE(("leave buf_get_rsa_priv_key")) 134 TRACE(("leave buf_get_rsa_priv_key"))
120 return DROPBEAR_SUCCESS; 135 return ret;
121 } 136 }
122 137
123 138
124 /* Clear and free the memory used by a public or private key */ 139 /* Clear and free the memory used by a public or private key */
125 void rsa_key_free(rsa_key *key) { 140 void rsa_key_free(rsa_key *key) {