5 Author: Pekka Riikonen <priikone@poseidon.pspt.fi>
7 Copyright (C) 1997 - 2001 Pekka Riikonen
9 This program is free software; you can redistribute it and/or modify
10 it under the terms of the GNU General Public License as published by
11 the Free Software Foundation; either version 2 of the License, or
12 (at your option) any later version.
14 This program is distributed in the hope that it will be useful,
15 but WITHOUT ANY WARRANTY; without even the implied warranty of
16 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17 GNU General Public License for more details.
22 #include "silcincludes.h"
27 /* List of all PKCS's in SILC. PKCS's don't support SIM's thus
28 only static declarations are possible. XXX: I hope this to change
30 SilcPKCSObject silc_pkcs_list[] =
32 /* RSA with PKCS #1 (Uses directly routines from Raw RSA operations) */
33 { "rsa", &silc_rsa_data_context,
34 silc_rsa_init, silc_rsa_clear_keys, silc_rsa_get_public_key,
35 silc_rsa_get_private_key, silc_rsa_set_public_key,
36 silc_rsa_set_private_key, silc_rsa_context_len,
37 silc_rsa_data_context_len, silc_rsa_set_arg,
38 silc_pkcs1_encrypt, silc_pkcs1_decrypt,
39 silc_pkcs1_sign, silc_pkcs1_verify },
41 /* Raw RSA operations */
42 { "rsa-raw", &silc_rsa_data_context,
43 silc_rsa_init, silc_rsa_clear_keys, silc_rsa_get_public_key,
44 silc_rsa_get_private_key, silc_rsa_set_public_key,
45 silc_rsa_set_private_key, silc_rsa_context_len,
46 silc_rsa_data_context_len, silc_rsa_set_arg,
47 silc_rsa_encrypt, silc_rsa_decrypt,
48 silc_rsa_sign, silc_rsa_verify },
50 { NULL, NULL, NULL, NULL, NULL,
51 NULL, NULL, NULL, NULL, NULL, NULL }
54 /* Allocates a new SilcPKCS object. The new allocated object is returned
55 to the 'new_pkcs' argument. This function also initializes the data
56 context structure. Function returns 1 on success and 0 on error.
59 int silc_pkcs_alloc(const unsigned char *name, SilcPKCS *new_pkcs)
63 SILC_LOG_DEBUG(("Allocating new PKCS object"));
65 for (i = 0; silc_pkcs_list[i].name; i++) {
66 if (!strcmp(silc_pkcs_list[i].name, name))
70 if (silc_pkcs_list[i].name == NULL)
73 *new_pkcs = silc_calloc(1, sizeof(**new_pkcs));
75 /* Set the pointers */
76 (*new_pkcs)->pkcs = &silc_pkcs_list[i];
77 (*new_pkcs)->pkcs->data_context =
78 silc_calloc(1, (*new_pkcs)->pkcs->data_context_len());
79 (*new_pkcs)->context = silc_calloc(1, (*new_pkcs)->pkcs->context_len());
80 (*new_pkcs)->get_key_len = silc_pkcs_get_key_len;
85 /* Free's the PKCS object */
87 void silc_pkcs_free(SilcPKCS pkcs)
90 silc_free(pkcs->context);
93 /* Return TRUE if PKCS algorithm `name' is supported. */
95 int silc_pkcs_is_supported(const unsigned char *name)
102 for (i = 0; silc_pkcs_list[i].name; i++) {
103 if (!strcmp(silc_pkcs_list[i].name, name))
110 /* Returns comma separated list of supported PKCS algorithms */
112 char *silc_pkcs_get_supported()
118 for (i = 0; silc_pkcs_list[i].name; i++) {
119 len += strlen(silc_pkcs_list[i].name);
120 list = silc_realloc(list, len + 1);
122 memcpy(list + (len - strlen(silc_pkcs_list[i].name)),
123 silc_pkcs_list[i].name, strlen(silc_pkcs_list[i].name));
124 memcpy(list + len, ",", 1);
133 /* Returns the length of the key */
135 uint32 silc_pkcs_get_key_len(SilcPKCS self)
137 return self->key_len;
140 /* Returns SILC style public key */
142 unsigned char *silc_pkcs_get_public_key(SilcPKCS pkcs, uint32 *len)
144 return pkcs->pkcs->get_public_key(pkcs->context, len);
147 /* Returns SILC style private key */
149 unsigned char *silc_pkcs_get_private_key(SilcPKCS pkcs, uint32 *len)
151 return pkcs->pkcs->get_private_key(pkcs->context, len);
154 /* Sets public key from SilcPublicKey. */
156 int silc_pkcs_public_key_set(SilcPKCS pkcs, SilcPublicKey public_key)
158 return pkcs->pkcs->set_public_key(pkcs->context, public_key->pk,
162 /* Sets public key from data. */
164 int silc_pkcs_public_key_data_set(SilcPKCS pkcs, unsigned char *pk,
167 return pkcs->pkcs->set_public_key(pkcs->context, pk, pk_len);
170 /* Sets private key from SilcPrivateKey. */
172 int silc_pkcs_private_key_set(SilcPKCS pkcs, SilcPrivateKey private_key)
174 return pkcs->pkcs->set_private_key(pkcs->context, private_key->prv,
175 private_key->prv_len);
178 /* Sets private key from data. */
180 int silc_pkcs_private_key_data_set(SilcPKCS pkcs, unsigned char *prv,
183 return pkcs->pkcs->set_private_key(pkcs->context, prv, prv_len);
188 int silc_pkcs_encrypt(SilcPKCS pkcs, unsigned char *src, uint32 src_len,
189 unsigned char *dst, uint32 *dst_len)
191 return pkcs->pkcs->encrypt(pkcs->context, src, src_len, dst, dst_len);
196 int silc_pkcs_decrypt(SilcPKCS pkcs, unsigned char *src, uint32 src_len,
197 unsigned char *dst, uint32 *dst_len)
199 return pkcs->pkcs->decrypt(pkcs->context, src, src_len, dst, dst_len);
202 /* Generates signature */
204 int silc_pkcs_sign(SilcPKCS pkcs, unsigned char *src, uint32 src_len,
205 unsigned char *dst, uint32 *dst_len)
207 return pkcs->pkcs->sign(pkcs->context, src, src_len, dst, dst_len);
210 /* Verifies signature */
212 int silc_pkcs_verify(SilcPKCS pkcs, unsigned char *signature,
213 uint32 signature_len, unsigned char *data,
216 return pkcs->pkcs->verify(pkcs->context, signature, signature_len,
220 /* Generates signature with hash. The hash is signed. */
222 int silc_pkcs_sign_with_hash(SilcPKCS pkcs, SilcHash hash,
223 unsigned char *src, uint32 src_len,
224 unsigned char *dst, uint32 *dst_len)
226 unsigned char hashr[32];
230 silc_hash_make(hash, src, src_len, hashr);
231 hash_len = hash->hash->hash_len;
233 SILC_LOG_HEXDUMP(("Hash"), hashr, hash_len);
235 ret = pkcs->pkcs->sign(pkcs->context, hashr, hash_len, dst, dst_len);
236 memset(hashr, 0, sizeof(hashr));
241 /* Verifies signature with hash. The `data' is hashed and verified against
244 int silc_pkcs_verify_with_hash(SilcPKCS pkcs, SilcHash hash,
245 unsigned char *signature,
246 uint32 signature_len,
250 unsigned char hashr[32];
254 silc_hash_make(hash, data, data_len, hashr);
255 hash_len = hash->hash->hash_len;
257 SILC_LOG_HEXDUMP(("Hash"), hashr, hash_len);
259 ret = pkcs->pkcs->verify(pkcs->context, signature, signature_len,
261 memset(hashr, 0, sizeof(hashr));
266 /* Encodes and returns SILC public key identifier. If some of the
267 arguments is NULL those are not encoded into the identifier string.
268 Protocol says that at least username and host must be provided. */
270 char *silc_pkcs_encode_identifier(char *username, char *host, char *realname,
271 char *email, char *org, char *country)
275 uint32 len, tlen = 0;
277 if (!username || !host)
280 len = (username ? strlen(username) : 0) +
281 (host ? strlen(host) : 0) +
282 (realname ? strlen(realname) : 0) +
283 (email ? strlen(email) : 0) +
284 (org ? strlen(org) : 0) +
285 (country ? strlen(country) : 0);
290 len += 3 + 5 + 5 + 4 + 4 + 4;
291 buf = silc_buffer_alloc(len);
292 silc_buffer_pull_tail(buf, len);
295 silc_buffer_format(buf,
296 SILC_STR_UI32_STRING("UN="),
297 SILC_STR_UI32_STRING(username),
299 silc_buffer_pull(buf, 3 + strlen(username));
300 tlen = 3 + strlen(username);
304 silc_buffer_format(buf,
305 SILC_STR_UI32_STRING(", "),
306 SILC_STR_UI32_STRING("HN="),
307 SILC_STR_UI32_STRING(host),
309 silc_buffer_pull(buf, 5 + strlen(host));
310 tlen += 5 + strlen(host);
314 silc_buffer_format(buf,
315 SILC_STR_UI32_STRING(", "),
316 SILC_STR_UI32_STRING("RN="),
317 SILC_STR_UI32_STRING(realname),
319 silc_buffer_pull(buf, 5 + strlen(realname));
320 tlen += 5 + strlen(realname);
324 silc_buffer_format(buf,
325 SILC_STR_UI32_STRING(", "),
326 SILC_STR_UI32_STRING("E="),
327 SILC_STR_UI32_STRING(email),
329 silc_buffer_pull(buf, 4 + strlen(email));
330 tlen += 4 + strlen(email);
334 silc_buffer_format(buf,
335 SILC_STR_UI32_STRING(", "),
336 SILC_STR_UI32_STRING("O="),
337 SILC_STR_UI32_STRING(org),
339 silc_buffer_pull(buf, 4 + strlen(org));
340 tlen += 4 + strlen(org);
344 silc_buffer_format(buf,
345 SILC_STR_UI32_STRING(", "),
346 SILC_STR_UI32_STRING("C="),
347 SILC_STR_UI32_STRING(country),
349 silc_buffer_pull(buf, 4 + strlen(country));
350 tlen += 4 + strlen(country);
353 silc_buffer_push(buf, buf->data - buf->head);
354 identifier = silc_calloc(tlen + 1, sizeof(*identifier));
355 memcpy(identifier, buf->data, tlen);
356 silc_buffer_free(buf);
361 /* Allocates SILC style public key formed from sent arguments. All data
364 SilcPublicKey silc_pkcs_public_key_alloc(char *name, char *identifier,
368 SilcPublicKey public_key;
370 public_key = silc_calloc(1, sizeof(*public_key));
371 public_key->len = 4 + 2 + strlen(name) + 2 + strlen(identifier) + pk_len;
372 public_key->name = strdup(name);
373 public_key->identifier = strdup(identifier);
374 public_key->pk_len = pk_len;
375 public_key->pk = silc_calloc(pk_len, sizeof(*public_key->pk));
376 memcpy(public_key->pk, pk, pk_len);
381 /* Free's public key */
383 void silc_pkcs_public_key_free(SilcPublicKey public_key)
386 silc_free(public_key->name);
387 silc_free(public_key->identifier);
388 silc_free(public_key->pk);
389 silc_free(public_key);
393 /* Allocates SILC private key formed from sent arguments. All data is
396 SilcPrivateKey silc_pkcs_private_key_alloc(char *name, unsigned char *prv,
399 SilcPrivateKey private_key;
401 private_key = silc_calloc(1, sizeof(*private_key));
402 private_key->name = strdup(name);
403 private_key->prv_len = prv_len;
404 private_key->prv = silc_calloc(prv_len, sizeof(*private_key->prv));
405 memcpy(private_key->prv, prv, prv_len);
410 /* Free's private key */
412 void silc_pkcs_private_key_free(SilcPrivateKey private_key)
415 silc_free(private_key->name);
416 silc_free(private_key->prv);
417 silc_free(private_key);
421 /* Encodes SILC style public key from SilcPublicKey. Returns the encoded
425 silc_pkcs_public_key_encode(SilcPublicKey public_key, uint32 *len)
430 buf = silc_buffer_alloc(public_key->len);
431 silc_buffer_pull_tail(buf, SILC_BUFFER_END(buf));
433 silc_buffer_format(buf,
434 SILC_STR_UI_INT(public_key->len),
435 SILC_STR_UI_SHORT(strlen(public_key->name)),
436 SILC_STR_UI32_STRING(public_key->name),
437 SILC_STR_UI_SHORT(strlen(public_key->identifier)),
438 SILC_STR_UI32_STRING(public_key->identifier),
439 SILC_STR_UI_XNSTRING(public_key->pk,
443 *len = public_key->len;
445 ret = silc_calloc(buf->len, sizeof(*ret));
446 memcpy(ret, buf->data, buf->len);
447 silc_buffer_free(buf);
452 /* Encodes SILC style public key. Returns the encoded data. */
455 silc_pkcs_public_key_data_encode(unsigned char *pk, uint32 pk_len,
456 char *pkcs, char *identifier,
463 totlen = 4 + 2 + strlen(pkcs) + 2 + strlen(identifier) + pk_len;
464 buf = silc_buffer_alloc(totlen);
465 silc_buffer_pull_tail(buf, SILC_BUFFER_END(buf));
467 silc_buffer_format(buf,
468 SILC_STR_UI_INT(totlen),
469 SILC_STR_UI_SHORT(strlen(pkcs)),
470 SILC_STR_UI32_STRING(pkcs),
471 SILC_STR_UI_SHORT(strlen(identifier)),
472 SILC_STR_UI32_STRING(identifier),
473 SILC_STR_UI_XNSTRING(pk, pk_len),
478 ret = silc_calloc(buf->len, sizeof(*ret));
479 memcpy(ret, buf->data, buf->len);
480 silc_buffer_free(buf);
485 /* Decodes SILC style public key. Returns TRUE if the decoding was
486 successful. Allocates new public key as well. */
488 int silc_pkcs_public_key_decode(unsigned char *data, uint32 data_len,
489 SilcPublicKey *public_key)
493 uint16 pkcs_len, identifier_len;
494 uint32 totlen, key_len;
495 unsigned char *pkcs_name = NULL, *ident = NULL, *key_data = NULL;
498 buf = silc_buffer_alloc(data_len);
499 silc_buffer_pull_tail(buf, SILC_BUFFER_END(buf));
500 silc_buffer_put(buf, data, data_len);
503 ret = silc_buffer_unformat(buf,
504 SILC_STR_UI_INT(&totlen),
507 silc_buffer_free(buf);
511 if (totlen != data_len) {
512 silc_buffer_free(buf);
516 /* Get algorithm name and identifier */
517 silc_buffer_pull(buf, 4);
519 silc_buffer_unformat(buf,
520 SILC_STR_UI16_NSTRING_ALLOC(&pkcs_name, &pkcs_len),
521 SILC_STR_UI16_NSTRING_ALLOC(&ident, &identifier_len),
526 if (pkcs_len < 1 || identifier_len < 3 ||
527 pkcs_len + identifier_len > totlen)
530 /* See if we support this algorithm */
531 if (!silc_pkcs_is_supported(pkcs_name))
534 /* Protocol says that at least UN and HN must be provided as identifier,
536 if (!strstr(ident, "UN=") && !strstr(ident, "HN="))
539 /* Get key data. We assume that rest of the buffer is key data. */
540 silc_buffer_pull(buf, 2 + pkcs_len + 2 + identifier_len);
542 ret = silc_buffer_unformat(buf,
543 SILC_STR_UI_XNSTRING_ALLOC(&key_data, key_len),
548 /* Try to set the key. If this fails the key must be malformed. This
549 code assumes that the PKCS routine checks the format of the key. */
550 silc_pkcs_alloc(pkcs_name, &alg);
551 if (!alg->pkcs->set_public_key(alg->context, key_data, key_len))
556 *public_key = silc_calloc(1, sizeof(**public_key));
557 (*public_key)->len = totlen;
558 (*public_key)->name = pkcs_name;
559 (*public_key)->identifier = ident;
560 (*public_key)->pk = key_data;
561 (*public_key)->pk_len = key_len;
564 silc_buffer_free(buf);
569 silc_free(pkcs_name);
574 silc_buffer_free(buf);
578 /* Encodes SILC private key from SilcPrivateKey. Returns the encoded data. */
581 silc_pkcs_private_key_encode(SilcPrivateKey private_key, uint32 *len)
587 totlen = 2 + strlen(private_key->name) + private_key->prv_len;
588 buf = silc_buffer_alloc(totlen);
589 silc_buffer_pull_tail(buf, SILC_BUFFER_END(buf));
591 silc_buffer_format(buf,
592 SILC_STR_UI_SHORT(strlen(private_key->name)),
593 SILC_STR_UI32_STRING(private_key->name),
594 SILC_STR_UI_XNSTRING(private_key->prv,
595 private_key->prv_len),
600 ret = silc_calloc(buf->len, sizeof(*ret));
601 memcpy(ret, buf->data, buf->len);
602 silc_buffer_free(buf);
607 /* Encodes SILC private key. Returns the encoded data. */
610 silc_pkcs_private_key_data_encode(unsigned char *prv, uint32 prv_len,
611 char *pkcs, uint32 *len)
617 totlen = 2 + strlen(pkcs) + prv_len;
618 buf = silc_buffer_alloc(totlen);
619 silc_buffer_pull_tail(buf, totlen);
621 silc_buffer_format(buf,
622 SILC_STR_UI_SHORT(strlen(pkcs)),
623 SILC_STR_UI32_STRING(pkcs),
624 SILC_STR_UI_XNSTRING(prv, prv_len),
629 ret = silc_calloc(buf->len, sizeof(*ret));
630 memcpy(ret, buf->data, buf->len);
631 silc_buffer_free(buf);
636 /* Decodes SILC style public key. Returns TRUE if the decoding was
637 successful. Allocates new private key as well. */
639 int silc_pkcs_private_key_decode(unsigned char *data, uint32 data_len,
640 SilcPrivateKey *private_key)
646 unsigned char *pkcs_name = NULL, *key_data = NULL;
649 buf = silc_buffer_alloc(data_len);
650 silc_buffer_pull_tail(buf, SILC_BUFFER_END(buf));
651 silc_buffer_put(buf, data, data_len);
653 /* Get algorithm name and identifier */
655 silc_buffer_unformat(buf,
656 SILC_STR_UI16_NSTRING_ALLOC(&pkcs_name, &pkcs_len),
661 if (pkcs_len < 1 || pkcs_len > buf->truelen)
664 /* See if we support this algorithm */
665 if (!silc_pkcs_is_supported(pkcs_name))
668 /* Get key data. We assume that rest of the buffer is key data. */
669 silc_buffer_pull(buf, 2 + pkcs_len);
671 ret = silc_buffer_unformat(buf,
672 SILC_STR_UI_XNSTRING_ALLOC(&key_data, key_len),
677 /* Try to set the key. If this fails the key must be malformed. This
678 code assumes that the PKCS routine checks the format of the key. */
679 silc_pkcs_alloc(pkcs_name, &alg);
680 if (!alg->pkcs->set_private_key(alg->context, key_data, key_len))
685 *private_key = silc_calloc(1, sizeof(**private_key));
686 (*private_key)->name = pkcs_name;
687 (*private_key)->prv = key_data;
688 (*private_key)->prv_len = key_len;
691 silc_buffer_free(buf);
696 silc_free(pkcs_name);
699 silc_buffer_free(buf);
703 /* Internal routine to save public key */
705 static int silc_pkcs_save_public_key_internal(char *filename,
714 case SILC_PKCS_FILE_BIN:
716 case SILC_PKCS_FILE_PEM:
717 data = silc_encode_pem_file(data, data_len);
718 data_len = strlen(data);
722 len = data_len + (strlen(SILC_PKCS_PUBLIC_KEYFILE_BEGIN) +
723 strlen(SILC_PKCS_PUBLIC_KEYFILE_END));
724 buf = silc_buffer_alloc(len);
725 silc_buffer_pull_tail(buf, SILC_BUFFER_END(buf));
727 silc_buffer_format(buf,
728 SILC_STR_UI32_STRING(SILC_PKCS_PUBLIC_KEYFILE_BEGIN),
729 SILC_STR_UI_XNSTRING(data, data_len),
730 SILC_STR_UI32_STRING(SILC_PKCS_PUBLIC_KEYFILE_END),
734 if (silc_file_write(filename, buf->data, buf->len)) {
735 silc_buffer_free(buf);
739 silc_buffer_free(buf);
743 /* Saves public key into file */
745 int silc_pkcs_save_public_key(char *filename, SilcPublicKey public_key,
751 data = silc_pkcs_public_key_encode(public_key, &data_len);
752 return silc_pkcs_save_public_key_internal(filename, data, data_len,
756 /* Saves public key into file */
758 int silc_pkcs_save_public_key_data(char *filename, unsigned char *data,
762 return silc_pkcs_save_public_key_internal(filename, data, data_len,
766 /* Internal routine to save private key. */
768 static int silc_pkcs_save_private_key_internal(char *filename,
777 case SILC_PKCS_FILE_BIN:
779 case SILC_PKCS_FILE_PEM:
780 data = silc_encode_pem_file(data, data_len);
781 data_len = strlen(data);
785 len = data_len + (strlen(SILC_PKCS_PRIVATE_KEYFILE_BEGIN) +
786 strlen(SILC_PKCS_PRIVATE_KEYFILE_END));
787 buf = silc_buffer_alloc(len);
788 silc_buffer_pull_tail(buf, SILC_BUFFER_END(buf));
790 silc_buffer_format(buf,
791 SILC_STR_UI32_STRING(SILC_PKCS_PRIVATE_KEYFILE_BEGIN),
792 SILC_STR_UI_XNSTRING(data, data_len),
793 SILC_STR_UI32_STRING(SILC_PKCS_PRIVATE_KEYFILE_END),
796 /* Save into a file */
797 if (silc_file_write_mode(filename, buf->data, buf->len, 0600)) {
798 silc_buffer_free(buf);
802 silc_buffer_free(buf);
806 /* Saves private key into file. */
807 /* XXX The buffer should be encrypted if passphrase is provided. */
809 int silc_pkcs_save_private_key(char *filename, SilcPrivateKey private_key,
810 unsigned char *passphrase,
816 data = silc_pkcs_private_key_encode(private_key, &data_len);
817 return silc_pkcs_save_private_key_internal(filename, data, data_len,
821 /* Saves private key into file. */
822 /* XXX The buffer should be encrypted if passphrase is provided. */
824 int silc_pkcs_save_private_key_data(char *filename, unsigned char *data,
826 unsigned char *passphrase,
829 return silc_pkcs_save_private_key_internal(filename, data, data_len,
833 /* Loads public key from file and allocates new public key. Returns TRUE
834 is loading was successful. */
836 int silc_pkcs_load_public_key(char *filename, SilcPublicKey *public_key,
839 unsigned char *cp, *old, *data, byte;
840 uint32 i, data_len, len;
842 old = data = silc_file_read(filename, &data_len);
846 /* Check start of file and remove header from the data. */
847 len = strlen(SILC_PKCS_PUBLIC_KEYFILE_BEGIN);
849 for (i = 0; i < len; i++) {
852 if (byte != SILC_PKCS_PUBLIC_KEYFILE_BEGIN[i]) {
853 memset(old, 0, data_len);
859 /* Decode public key */
861 len = data_len - (strlen(SILC_PKCS_PUBLIC_KEYFILE_BEGIN) +
862 strlen(SILC_PKCS_PUBLIC_KEYFILE_END));
865 case SILC_PKCS_FILE_BIN:
867 case SILC_PKCS_FILE_PEM:
868 data = silc_decode_pem(data, len, &len);
872 if (!data || !silc_pkcs_public_key_decode(data, len, public_key)) {
873 memset(old, 0, data_len);
879 memset(old, 0, data_len);
884 /* Load private key from file and allocates new private key. Returns TRUE
885 if loading was successful. */
886 /* XXX Should support encrypted private key files */
888 int silc_pkcs_load_private_key(char *filename, SilcPrivateKey *private_key,
891 unsigned char *cp, *old, *data, byte;
892 uint32 i, data_len, len;
894 old = data = silc_file_read(filename, &data_len);
898 /* Check start of file and remove header from the data. */
899 len = strlen(SILC_PKCS_PRIVATE_KEYFILE_BEGIN);
901 for (i = 0; i < len; i++) {
904 if (byte != SILC_PKCS_PRIVATE_KEYFILE_BEGIN[i]) {
905 memset(old, 0, data_len);
911 /* Decode private key */
913 len = data_len - (strlen(SILC_PKCS_PRIVATE_KEYFILE_BEGIN) +
914 strlen(SILC_PKCS_PRIVATE_KEYFILE_END));
917 case SILC_PKCS_FILE_BIN:
919 case SILC_PKCS_FILE_PEM:
920 data = silc_decode_pem(data, len, &len);
924 if (!data || !silc_pkcs_private_key_decode(data, len, private_key)) {
925 memset(old, 0, data_len);
931 memset(old, 0, data_len);