- memcpy(tmp, key_data, 4);
- SILC_GET32_MSB(e_len, tmp);
- if (e_len + 4 > key_len) {
- silc_mp_uninit(&key->e);
- silc_mp_uninit(&key->n);
- silc_mp_uninit(&key->d);
- return FALSE;
- }
-
- silc_mp_bin2mp(key_data + 4, e_len, &key->e);
-
- if (key_len < e_len + 4 + 4) {
- silc_mp_uninit(&key->e);
- silc_mp_uninit(&key->n);
- silc_mp_uninit(&key->d);
- return FALSE;
- }
-
- memcpy(tmp, key_data + 4 + e_len, 4);
- SILC_GET32_MSB(n_len, tmp);
- if (e_len + 4 + n_len + 4 > key_len) {
- silc_mp_uninit(&key->e);
- silc_mp_uninit(&key->n);
- silc_mp_uninit(&key->d);
- return FALSE;
- }
-
- silc_mp_bin2mp(key_data + 4 + e_len + 4, n_len, &key->n);
-
- if (key_len < e_len + 4 + n_len + 4 + 4) {
- silc_mp_uninit(&key->e);
- silc_mp_uninit(&key->n);
- silc_mp_uninit(&key->d);
- return FALSE;
- }
-
- memcpy(tmp, key_data + 4 + e_len + 4 + n_len, 4);
- SILC_GET32_MSB(d_len, tmp);
- if (e_len + 4 + n_len + 4 + d_len + 4 > key_len) {
- silc_mp_uninit(&key->e);
- silc_mp_uninit(&key->n);
- silc_mp_uninit(&key->d);
- return FALSE;
+ /* Get e */
+ if (silc_buffer_unformat(&k,
+ SILC_STR_UI_INT(&len),
+ SILC_STR_END) < 0)
+ goto err;
+ silc_buffer_pull(&k, 4);
+ if (silc_buffer_unformat(&k,
+ SILC_STR_UI_XNSTRING(&tmp, len),
+ SILC_STR_END) < 0)
+ goto err;
+ silc_mp_bin2mp(tmp, len, &key->e);
+ silc_buffer_pull(&k, len);
+
+ /* Get n */
+ if (silc_buffer_unformat(&k,
+ SILC_STR_UI_INT(&len),
+ SILC_STR_END) < 0)
+ goto err;
+ silc_buffer_pull(&k, 4);
+ if (silc_buffer_unformat(&k,
+ SILC_STR_UI_XNSTRING(&tmp, len),
+ SILC_STR_END) < 0)
+ goto err;
+ silc_mp_bin2mp(tmp, len, &key->n);
+ silc_buffer_pull(&k, len);
+
+ /* Get d */
+ if (silc_buffer_unformat(&k,
+ SILC_STR_UI_INT(&len),
+ SILC_STR_END) < 0)
+ goto err;
+ silc_buffer_pull(&k, 4);
+ if (silc_buffer_unformat(&k,
+ SILC_STR_UI_XNSTRING(&tmp, len),
+ SILC_STR_END) < 0)
+ goto err;
+ silc_mp_bin2mp(tmp, len, &key->d);
+ silc_buffer_pull(&k, len);
+
+ /* Get optimized d for CRT, if present. */
+ if (k.len > 4) {
+ key->crt = TRUE;
+ silc_mp_init(&key->dP);
+ silc_mp_init(&key->dQ);
+ silc_mp_init(&key->pQ);
+ silc_mp_init(&key->qP);
+ silc_mp_init(&key->p);
+ silc_mp_init(&key->q);
+
+ /* Get dP */
+ if (silc_buffer_unformat(&k,
+ SILC_STR_UI_INT(&len),
+ SILC_STR_END) < 0)
+ goto err;
+ silc_buffer_pull(&k, 4);
+ if (silc_buffer_unformat(&k,
+ SILC_STR_UI_XNSTRING(&tmp, len),
+ SILC_STR_END) < 0)
+ goto err;
+ silc_mp_bin2mp(tmp, len, &key->dP);
+ silc_buffer_pull(&k, len);
+
+ /* Get dQ */
+ if (silc_buffer_unformat(&k,
+ SILC_STR_UI_INT(&len),
+ SILC_STR_END) < 0)
+ goto err;
+ silc_buffer_pull(&k, 4);
+ if (silc_buffer_unformat(&k,
+ SILC_STR_UI_XNSTRING(&tmp, len),
+ SILC_STR_END) < 0)
+ goto err;
+ silc_mp_bin2mp(tmp, len, &key->dQ);
+ silc_buffer_pull(&k, len);
+
+ /* Get pQ */
+ if (silc_buffer_unformat(&k,
+ SILC_STR_UI_INT(&len),
+ SILC_STR_END) < 0)
+ goto err;
+ silc_buffer_pull(&k, 4);
+ if (silc_buffer_unformat(&k,
+ SILC_STR_UI_XNSTRING(&tmp, len),
+ SILC_STR_END) < 0)
+ goto err;
+ silc_mp_bin2mp(tmp, len, &key->pQ);
+ silc_buffer_pull(&k, len);
+
+ /* Get qP */
+ if (silc_buffer_unformat(&k,
+ SILC_STR_UI_INT(&len),
+ SILC_STR_END) < 0)
+ goto err;
+ silc_buffer_pull(&k, 4);
+ if (silc_buffer_unformat(&k,
+ SILC_STR_UI_XNSTRING(&tmp, len),
+ SILC_STR_END) < 0)
+ goto err;
+ silc_mp_bin2mp(tmp, len, &key->qP);
+ silc_buffer_pull(&k, len);
+
+ /* Get p */
+ if (silc_buffer_unformat(&k,
+ SILC_STR_UI_INT(&len),
+ SILC_STR_END) < 0)
+ goto err;
+ silc_buffer_pull(&k, 4);
+ if (silc_buffer_unformat(&k,
+ SILC_STR_UI_XNSTRING(&tmp, len),
+ SILC_STR_END) < 0)
+ goto err;
+ silc_mp_bin2mp(tmp, len, &key->p);
+ silc_buffer_pull(&k, len);
+
+ /* Get q */
+ if (silc_buffer_unformat(&k,
+ SILC_STR_UI_INT(&len),
+ SILC_STR_END) < 0)
+ goto err;
+ silc_buffer_pull(&k, 4);
+ if (silc_buffer_unformat(&k,
+ SILC_STR_UI_XNSTRING(&tmp, len),
+ SILC_STR_END) < 0)
+ goto err;
+ silc_mp_bin2mp(tmp, len, &key->q);
+ silc_buffer_pull(&k, len);