comparison dss.c @ 1381:c98e242dc505 fuzz

add m_mp_free_multi, be more careful freeing when failing to load keys
author Matt Johnston <matt@ucc.asn.au>
date Fri, 26 May 2017 21:08:43 +0800
parents 750ec4ec4cbe
children 771e4a7051e0
comparison
equal deleted inserted replaced
1380:d201105df2ed 1381:c98e242dc505
42 /* Load a dss key from a buffer, initialising the values. 42 /* Load a dss key from a buffer, initialising the values.
43 * The key will have the same format as buf_put_dss_key. 43 * The key will have the same format as buf_put_dss_key.
44 * These should be freed with dss_key_free. 44 * These should be freed with dss_key_free.
45 * Returns DROPBEAR_SUCCESS or DROPBEAR_FAILURE */ 45 * Returns DROPBEAR_SUCCESS or DROPBEAR_FAILURE */
46 int buf_get_dss_pub_key(buffer* buf, dropbear_dss_key *key) { 46 int buf_get_dss_pub_key(buffer* buf, dropbear_dss_key *key) {
47 int ret = DROPBEAR_FAILURE;
47 48
48 TRACE(("enter buf_get_dss_pub_key")) 49 TRACE(("enter buf_get_dss_pub_key"))
49 dropbear_assert(key != NULL); 50 dropbear_assert(key != NULL);
50 m_mp_alloc_init_multi(&key->p, &key->q, &key->g, &key->y, NULL); 51 m_mp_alloc_init_multi(&key->p, &key->q, &key->g, &key->y, NULL);
51 key->x = NULL; 52 key->x = NULL;
54 if (buf_getmpint(buf, key->p) == DROPBEAR_FAILURE 55 if (buf_getmpint(buf, key->p) == DROPBEAR_FAILURE
55 || buf_getmpint(buf, key->q) == DROPBEAR_FAILURE 56 || buf_getmpint(buf, key->q) == DROPBEAR_FAILURE
56 || buf_getmpint(buf, key->g) == DROPBEAR_FAILURE 57 || buf_getmpint(buf, key->g) == DROPBEAR_FAILURE
57 || buf_getmpint(buf, key->y) == DROPBEAR_FAILURE) { 58 || buf_getmpint(buf, key->y) == DROPBEAR_FAILURE) {
58 TRACE(("leave buf_get_dss_pub_key: failed reading mpints")) 59 TRACE(("leave buf_get_dss_pub_key: failed reading mpints"))
59 return DROPBEAR_FAILURE; 60 ret = DROPBEAR_FAILURE;
61 goto out;
60 } 62 }
61 63
62 if (mp_count_bits(key->p) < MIN_DSS_KEYLEN) { 64 if (mp_count_bits(key->p) < MIN_DSS_KEYLEN) {
63 dropbear_log(LOG_WARNING, "DSS key too short"); 65 dropbear_log(LOG_WARNING, "DSS key too short");
64 TRACE(("leave buf_get_dss_pub_key: short key")) 66 TRACE(("leave buf_get_dss_pub_key: short key"))
65 return DROPBEAR_FAILURE; 67 ret = DROPBEAR_FAILURE;
66 } 68 goto out;
67 69 }
70
71 ret = DROPBEAR_SUCCESS;
68 TRACE(("leave buf_get_dss_pub_key: success")) 72 TRACE(("leave buf_get_dss_pub_key: success"))
69 return DROPBEAR_SUCCESS; 73 out:
74 if (ret == DROPBEAR_FAILURE) {
75 m_mp_free_multi(&key->p, &key->q, &key->g, &key->y, NULL);
76 }
77 return ret;
70 } 78 }
71 79
72 /* Same as buf_get_dss_pub_key, but reads a private "x" key at the end. 80 /* Same as buf_get_dss_pub_key, but reads a private "x" key at the end.
73 * Loads a private dss key from a buffer 81 * Loads a private dss key from a buffer
74 * Returns DROPBEAR_SUCCESS or DROPBEAR_FAILURE */ 82 * Returns DROPBEAR_SUCCESS or DROPBEAR_FAILURE */
84 } 92 }
85 93
86 m_mp_alloc_init_multi(&key->x, NULL); 94 m_mp_alloc_init_multi(&key->x, NULL);
87 ret = buf_getmpint(buf, key->x); 95 ret = buf_getmpint(buf, key->x);
88 if (ret == DROPBEAR_FAILURE) { 96 if (ret == DROPBEAR_FAILURE) {
89 m_free(key->x); 97 m_mp_free_multi(&key->x);
90 } 98 }
91 99
92 return ret; 100 return ret;
93 } 101 }
94 102
99 TRACE2(("enter dsa_key_free")) 107 TRACE2(("enter dsa_key_free"))
100 if (key == NULL) { 108 if (key == NULL) {
101 TRACE2(("enter dsa_key_free: key == NULL")) 109 TRACE2(("enter dsa_key_free: key == NULL"))
102 return; 110 return;
103 } 111 }
104 if (key->p) { 112 m_mp_free_multi(&key->p, &key->q, &key->g, &key->y, &key->x, NULL);
105 mp_clear(key->p);
106 m_free(key->p);
107 }
108 if (key->q) {
109 mp_clear(key->q);
110 m_free(key->q);
111 }
112 if (key->g) {
113 mp_clear(key->g);
114 m_free(key->g);
115 }
116 if (key->y) {
117 mp_clear(key->y);
118 m_free(key->y);
119 }
120 if (key->x) {
121 mp_clear(key->x);
122 m_free(key->x);
123 }
124 m_free(key); 113 m_free(key);
125 TRACE2(("leave dsa_key_free")) 114 TRACE2(("leave dsa_key_free"))
126 } 115 }
127 116
128 /* put the dss public key into the buffer in the required format: 117 /* put the dss public key into the buffer in the required format: