- SilcBuffer buf;
- unsigned char *ret;
- SilcUInt32 totlen;
-
- totlen = 2 + strlen(private_key->name) + private_key->prv_len;
- buf = silc_buffer_alloc(totlen);
- silc_buffer_pull_tail(buf, SILC_BUFFER_END(buf));
-
- silc_buffer_format(buf,
- SILC_STR_UI_SHORT(strlen(private_key->name)),
- SILC_STR_UI32_STRING(private_key->name),
- SILC_STR_UI_XNSTRING(private_key->prv,
- private_key->prv_len),
- SILC_STR_END);
- if (len)
- *len = totlen;
-
- ret = silc_calloc(buf->len, sizeof(*ret));
- memcpy(ret, buf->data, buf->len);
- silc_buffer_free(buf);
-
- return ret;
-}
-
-/* Encodes SILC private key. Returns the encoded data. */
-
-unsigned char *
-silc_pkcs_private_key_data_encode(unsigned char *prv, SilcUInt32 prv_len,
- char *pkcs, SilcUInt32 *len)
-{
- SilcBuffer buf;
- unsigned char *ret;
- SilcUInt32 totlen;
-
- totlen = 2 + strlen(pkcs) + prv_len;
- buf = silc_buffer_alloc(totlen);
- silc_buffer_pull_tail(buf, totlen);
-
- silc_buffer_format(buf,
- SILC_STR_UI_SHORT(strlen(pkcs)),
- SILC_STR_UI32_STRING(pkcs),
- SILC_STR_UI_XNSTRING(prv, prv_len),
- SILC_STR_END);
- if (len)
- *len = totlen;
-
- ret = silc_calloc(buf->len, sizeof(*ret));
- memcpy(ret, buf->data, buf->len);
- silc_buffer_free(buf);
-
- return ret;
-}
-
-/* Decodes SILC style public key. Returns TRUE if the decoding was
- successful. Allocates new private key as well. */
-
-int silc_pkcs_private_key_decode(unsigned char *data, SilcUInt32 data_len,
- SilcPrivateKey *private_key)
-{
- SilcBuffer buf;
- SilcPKCS alg;
- SilcUInt16 pkcs_len;
- SilcUInt32 key_len;
- unsigned char *pkcs_name = NULL, *key_data = NULL;
- int ret;
-
- buf = silc_buffer_alloc(data_len);
- silc_buffer_pull_tail(buf, SILC_BUFFER_END(buf));
- silc_buffer_put(buf, data, data_len);
-
- /* Get algorithm name and identifier */
- ret =
- silc_buffer_unformat(buf,
- SILC_STR_UI16_NSTRING_ALLOC(&pkcs_name, &pkcs_len),
- SILC_STR_END);
- if (ret == -1)
- goto err;
-
- if (pkcs_len < 1 || pkcs_len > buf->truelen)
- goto err;
-
- /* See if we support this algorithm (check only if PKCS are registered). */
- if (SILC_PKCS_LIST && !silc_pkcs_is_supported(pkcs_name)) {
- SILC_LOG_DEBUG(("Unknown PKCS `%s'", pkcs_name));
- goto err;
- }
-
- /* Get key data. We assume that rest of the buffer is key data. */
- silc_buffer_pull(buf, 2 + pkcs_len);
- key_len = buf->len;
- ret = silc_buffer_unformat(buf,
- SILC_STR_UI_XNSTRING_ALLOC(&key_data, key_len),
- SILC_STR_END);
- if (ret == -1)
- goto err;
-
- /* Try to set the key. If this fails the key must be malformed. This
- code assumes that the PKCS routine checks the format of the key.
- (check only if PKCS are registered) */
- if (SILC_PKCS_LIST) {
- silc_pkcs_alloc(pkcs_name, &alg);
- if (!alg->pkcs->set_private_key(alg->context, key_data, key_len))
- goto err;
- silc_pkcs_free(alg);
- }
-
- if (private_key) {
- *private_key = silc_calloc(1, sizeof(**private_key));
- (*private_key)->name = pkcs_name;
- (*private_key)->prv = key_data;
- (*private_key)->prv_len = key_len;
- }