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 uint32 silc_pkcs_public_key_set(SilcPKCS pkcs, SilcPublicKey public_key)
158 pkcs->key_len = pkcs->pkcs->set_public_key(pkcs->context, public_key->pk,
160 return pkcs->key_len;
163 /* Sets public key from data. */
165 uint32 silc_pkcs_public_key_data_set(SilcPKCS pkcs, unsigned char *pk,
168 pkcs->key_len = pkcs->pkcs->set_public_key(pkcs->context, pk, pk_len);
169 return pkcs->key_len;
172 /* Sets private key from SilcPrivateKey. */
174 int silc_pkcs_private_key_set(SilcPKCS pkcs, SilcPrivateKey private_key)
176 return pkcs->pkcs->set_private_key(pkcs->context, private_key->prv,
177 private_key->prv_len);
180 /* Sets private key from data. */
182 int silc_pkcs_private_key_data_set(SilcPKCS pkcs, unsigned char *prv,
185 return pkcs->pkcs->set_private_key(pkcs->context, prv, prv_len);
190 int silc_pkcs_encrypt(SilcPKCS pkcs, unsigned char *src, uint32 src_len,
191 unsigned char *dst, uint32 *dst_len)
193 return pkcs->pkcs->encrypt(pkcs->context, src, src_len, dst, dst_len);
198 int silc_pkcs_decrypt(SilcPKCS pkcs, unsigned char *src, uint32 src_len,
199 unsigned char *dst, uint32 *dst_len)
201 return pkcs->pkcs->decrypt(pkcs->context, src, src_len, dst, dst_len);
204 /* Generates signature */
206 int silc_pkcs_sign(SilcPKCS pkcs, unsigned char *src, uint32 src_len,
207 unsigned char *dst, uint32 *dst_len)
209 return pkcs->pkcs->sign(pkcs->context, src, src_len, dst, dst_len);
212 /* Verifies signature */
214 int silc_pkcs_verify(SilcPKCS pkcs, unsigned char *signature,
215 uint32 signature_len, unsigned char *data,
218 return pkcs->pkcs->verify(pkcs->context, signature, signature_len,
222 /* Generates signature with hash. The hash is signed. */
224 int silc_pkcs_sign_with_hash(SilcPKCS pkcs, SilcHash hash,
225 unsigned char *src, uint32 src_len,
226 unsigned char *dst, uint32 *dst_len)
228 unsigned char hashr[32];
232 silc_hash_make(hash, src, src_len, hashr);
233 hash_len = hash->hash->hash_len;
235 SILC_LOG_HEXDUMP(("Hash"), hashr, hash_len);
237 ret = pkcs->pkcs->sign(pkcs->context, hashr, hash_len, dst, dst_len);
238 memset(hashr, 0, sizeof(hashr));
243 /* Verifies signature with hash. The `data' is hashed and verified against
246 int silc_pkcs_verify_with_hash(SilcPKCS pkcs, SilcHash hash,
247 unsigned char *signature,
248 uint32 signature_len,
252 unsigned char hashr[32];
256 silc_hash_make(hash, data, data_len, hashr);
257 hash_len = hash->hash->hash_len;
259 SILC_LOG_HEXDUMP(("Hash"), hashr, hash_len);
261 ret = pkcs->pkcs->verify(pkcs->context, signature, signature_len,
263 memset(hashr, 0, sizeof(hashr));
268 /* Encodes and returns SILC public key identifier. If some of the
269 arguments is NULL those are not encoded into the identifier string.
270 Protocol says that at least username and host must be provided. */
272 char *silc_pkcs_encode_identifier(char *username, char *host, char *realname,
273 char *email, char *org, char *country)
277 uint32 len, tlen = 0;
279 if (!username || !host)
282 len = (username ? strlen(username) : 0) +
283 (host ? strlen(host) : 0) +
284 (realname ? strlen(realname) : 0) +
285 (email ? strlen(email) : 0) +
286 (org ? strlen(org) : 0) +
287 (country ? strlen(country) : 0);
292 len += 3 + 5 + 5 + 4 + 4 + 4;
293 buf = silc_buffer_alloc(len);
294 silc_buffer_pull_tail(buf, len);
297 silc_buffer_format(buf,
298 SILC_STR_UI32_STRING("UN="),
299 SILC_STR_UI32_STRING(username),
301 silc_buffer_pull(buf, 3 + strlen(username));
302 tlen = 3 + strlen(username);
306 silc_buffer_format(buf,
307 SILC_STR_UI32_STRING(", "),
308 SILC_STR_UI32_STRING("HN="),
309 SILC_STR_UI32_STRING(host),
311 silc_buffer_pull(buf, 5 + strlen(host));
312 tlen += 5 + strlen(host);
316 silc_buffer_format(buf,
317 SILC_STR_UI32_STRING(", "),
318 SILC_STR_UI32_STRING("RN="),
319 SILC_STR_UI32_STRING(realname),
321 silc_buffer_pull(buf, 5 + strlen(realname));
322 tlen += 5 + strlen(realname);
326 silc_buffer_format(buf,
327 SILC_STR_UI32_STRING(", "),
328 SILC_STR_UI32_STRING("E="),
329 SILC_STR_UI32_STRING(email),
331 silc_buffer_pull(buf, 4 + strlen(email));
332 tlen += 4 + strlen(email);
336 silc_buffer_format(buf,
337 SILC_STR_UI32_STRING(", "),
338 SILC_STR_UI32_STRING("O="),
339 SILC_STR_UI32_STRING(org),
341 silc_buffer_pull(buf, 4 + strlen(org));
342 tlen += 4 + strlen(org);
346 silc_buffer_format(buf,
347 SILC_STR_UI32_STRING(", "),
348 SILC_STR_UI32_STRING("C="),
349 SILC_STR_UI32_STRING(country),
351 silc_buffer_pull(buf, 4 + strlen(country));
352 tlen += 4 + strlen(country);
355 silc_buffer_push(buf, buf->data - buf->head);
356 identifier = silc_calloc(tlen + 1, sizeof(*identifier));
357 memcpy(identifier, buf->data, tlen);
358 silc_buffer_free(buf);
363 /* Decodes the provided `identifier' and returns allocated context for
366 SilcPublicKeyIdentifier silc_pkcs_decode_identifier(char *identifier)
368 SilcPublicKeyIdentifier ident;
372 ident = silc_calloc(1, sizeof(*ident));
376 len = strcspn(cp, ",");
377 item = silc_calloc(len + 1, sizeof(char));
378 memcpy(item, cp, len);
380 if (strstr(item, "UN="))
381 ident->username = strdup(item + 3);
382 else if (strstr(item, "HN="))
383 ident->host = strdup(item + 3);
384 else if (strstr(item, "RN="))
385 ident->realname = strdup(item + 3);
386 else if (strstr(item, "E="))
387 ident->email = strdup(item + 2);
388 else if (strstr(item, "O="))
389 ident->org = strdup(item + 2);
390 else if (strstr(item, "C="))
391 ident->country = strdup(item + 2);
406 /* Free's decoded public key identifier context. Call this to free the
407 context returned by the silc_pkcs_decode_identifier. */
409 void silc_pkcs_free_identifier(SilcPublicKeyIdentifier identifier)
411 silc_free(identifier->username);
412 silc_free(identifier->host);
413 silc_free(identifier->realname);
414 silc_free(identifier->email);
415 silc_free(identifier->org);
416 silc_free(identifier->country);
417 silc_free(identifier);
420 /* Allocates SILC style public key formed from sent arguments. All data
423 SilcPublicKey silc_pkcs_public_key_alloc(char *name, char *identifier,
427 SilcPublicKey public_key;
429 public_key = silc_calloc(1, sizeof(*public_key));
430 public_key->len = 4 + 2 + strlen(name) + 2 + strlen(identifier) + pk_len;
431 public_key->name = strdup(name);
432 public_key->identifier = strdup(identifier);
433 public_key->pk_len = pk_len;
434 public_key->pk = silc_calloc(pk_len, sizeof(*public_key->pk));
435 memcpy(public_key->pk, pk, pk_len);
440 /* Free's public key */
442 void silc_pkcs_public_key_free(SilcPublicKey public_key)
445 silc_free(public_key->name);
446 silc_free(public_key->identifier);
447 silc_free(public_key->pk);
448 silc_free(public_key);
452 /* Allocates SILC private key formed from sent arguments. All data is
455 SilcPrivateKey silc_pkcs_private_key_alloc(char *name, unsigned char *prv,
458 SilcPrivateKey private_key;
460 private_key = silc_calloc(1, sizeof(*private_key));
461 private_key->name = strdup(name);
462 private_key->prv_len = prv_len;
463 private_key->prv = silc_calloc(prv_len, sizeof(*private_key->prv));
464 memcpy(private_key->prv, prv, prv_len);
469 /* Free's private key */
471 void silc_pkcs_private_key_free(SilcPrivateKey private_key)
474 silc_free(private_key->name);
475 silc_free(private_key->prv);
476 silc_free(private_key);
480 /* Encodes SILC style public key from SilcPublicKey. Returns the encoded
484 silc_pkcs_public_key_encode(SilcPublicKey public_key, uint32 *len)
489 buf = silc_buffer_alloc(public_key->len);
490 silc_buffer_pull_tail(buf, SILC_BUFFER_END(buf));
492 silc_buffer_format(buf,
493 SILC_STR_UI_INT(public_key->len),
494 SILC_STR_UI_SHORT(strlen(public_key->name)),
495 SILC_STR_UI32_STRING(public_key->name),
496 SILC_STR_UI_SHORT(strlen(public_key->identifier)),
497 SILC_STR_UI32_STRING(public_key->identifier),
498 SILC_STR_UI_XNSTRING(public_key->pk,
502 *len = public_key->len;
504 ret = silc_calloc(buf->len, sizeof(*ret));
505 memcpy(ret, buf->data, buf->len);
506 silc_buffer_free(buf);
511 /* Encodes SILC style public key. Returns the encoded data. */
514 silc_pkcs_public_key_data_encode(unsigned char *pk, uint32 pk_len,
515 char *pkcs, char *identifier,
522 totlen = 4 + 2 + strlen(pkcs) + 2 + strlen(identifier) + pk_len;
523 buf = silc_buffer_alloc(totlen);
524 silc_buffer_pull_tail(buf, SILC_BUFFER_END(buf));
526 silc_buffer_format(buf,
527 SILC_STR_UI_INT(totlen),
528 SILC_STR_UI_SHORT(strlen(pkcs)),
529 SILC_STR_UI32_STRING(pkcs),
530 SILC_STR_UI_SHORT(strlen(identifier)),
531 SILC_STR_UI32_STRING(identifier),
532 SILC_STR_UI_XNSTRING(pk, pk_len),
537 ret = silc_calloc(buf->len, sizeof(*ret));
538 memcpy(ret, buf->data, buf->len);
539 silc_buffer_free(buf);
544 /* Decodes SILC style public key. Returns TRUE if the decoding was
545 successful. Allocates new public key as well. */
547 int silc_pkcs_public_key_decode(unsigned char *data, uint32 data_len,
548 SilcPublicKey *public_key)
552 uint16 pkcs_len, identifier_len;
553 uint32 totlen, key_len;
554 unsigned char *pkcs_name = NULL, *ident = NULL, *key_data = NULL;
557 buf = silc_buffer_alloc(data_len);
558 silc_buffer_pull_tail(buf, SILC_BUFFER_END(buf));
559 silc_buffer_put(buf, data, data_len);
562 ret = silc_buffer_unformat(buf,
563 SILC_STR_UI_INT(&totlen),
566 silc_buffer_free(buf);
570 if (totlen != data_len) {
571 silc_buffer_free(buf);
575 /* Get algorithm name and identifier */
576 silc_buffer_pull(buf, 4);
578 silc_buffer_unformat(buf,
579 SILC_STR_UI16_NSTRING_ALLOC(&pkcs_name, &pkcs_len),
580 SILC_STR_UI16_NSTRING_ALLOC(&ident, &identifier_len),
585 if (pkcs_len < 1 || identifier_len < 3 ||
586 pkcs_len + identifier_len > totlen)
589 /* See if we support this algorithm */
590 if (!silc_pkcs_is_supported(pkcs_name)) {
591 SILC_LOG_DEBUG(("Unsupported PKCS %s", pkcs_name));
595 /* Protocol says that at least UN and HN must be provided as identifier,
597 if (!strstr(ident, "UN=") && !strstr(ident, "HN=")) {
598 SILC_LOG_DEBUG(("The public does not have the required UN= and HN= "
603 /* Get key data. We assume that rest of the buffer is key data. */
604 silc_buffer_pull(buf, 2 + pkcs_len + 2 + identifier_len);
606 ret = silc_buffer_unformat(buf,
607 SILC_STR_UI_XNSTRING_ALLOC(&key_data, key_len),
612 /* Try to set the key. If this fails the key must be malformed. This
613 code assumes that the PKCS routine checks the format of the key. */
614 silc_pkcs_alloc(pkcs_name, &alg);
615 if (!alg->pkcs->set_public_key(alg->context, key_data, key_len))
620 *public_key = silc_calloc(1, sizeof(**public_key));
621 (*public_key)->len = totlen;
622 (*public_key)->name = pkcs_name;
623 (*public_key)->identifier = ident;
624 (*public_key)->pk = key_data;
625 (*public_key)->pk_len = key_len;
628 silc_buffer_free(buf);
633 silc_free(pkcs_name);
638 silc_buffer_free(buf);
642 /* Encodes SILC private key from SilcPrivateKey. Returns the encoded data. */
645 silc_pkcs_private_key_encode(SilcPrivateKey private_key, uint32 *len)
651 totlen = 2 + strlen(private_key->name) + private_key->prv_len;
652 buf = silc_buffer_alloc(totlen);
653 silc_buffer_pull_tail(buf, SILC_BUFFER_END(buf));
655 silc_buffer_format(buf,
656 SILC_STR_UI_SHORT(strlen(private_key->name)),
657 SILC_STR_UI32_STRING(private_key->name),
658 SILC_STR_UI_XNSTRING(private_key->prv,
659 private_key->prv_len),
664 ret = silc_calloc(buf->len, sizeof(*ret));
665 memcpy(ret, buf->data, buf->len);
666 silc_buffer_free(buf);
671 /* Encodes SILC private key. Returns the encoded data. */
674 silc_pkcs_private_key_data_encode(unsigned char *prv, uint32 prv_len,
675 char *pkcs, uint32 *len)
681 totlen = 2 + strlen(pkcs) + prv_len;
682 buf = silc_buffer_alloc(totlen);
683 silc_buffer_pull_tail(buf, totlen);
685 silc_buffer_format(buf,
686 SILC_STR_UI_SHORT(strlen(pkcs)),
687 SILC_STR_UI32_STRING(pkcs),
688 SILC_STR_UI_XNSTRING(prv, prv_len),
693 ret = silc_calloc(buf->len, sizeof(*ret));
694 memcpy(ret, buf->data, buf->len);
695 silc_buffer_free(buf);
700 /* Decodes SILC style public key. Returns TRUE if the decoding was
701 successful. Allocates new private key as well. */
703 int silc_pkcs_private_key_decode(unsigned char *data, uint32 data_len,
704 SilcPrivateKey *private_key)
710 unsigned char *pkcs_name = NULL, *key_data = NULL;
713 buf = silc_buffer_alloc(data_len);
714 silc_buffer_pull_tail(buf, SILC_BUFFER_END(buf));
715 silc_buffer_put(buf, data, data_len);
717 /* Get algorithm name and identifier */
719 silc_buffer_unformat(buf,
720 SILC_STR_UI16_NSTRING_ALLOC(&pkcs_name, &pkcs_len),
725 if (pkcs_len < 1 || pkcs_len > buf->truelen)
728 /* See if we support this algorithm */
729 if (!silc_pkcs_is_supported(pkcs_name))
732 /* Get key data. We assume that rest of the buffer is key data. */
733 silc_buffer_pull(buf, 2 + pkcs_len);
735 ret = silc_buffer_unformat(buf,
736 SILC_STR_UI_XNSTRING_ALLOC(&key_data, key_len),
741 /* Try to set the key. If this fails the key must be malformed. This
742 code assumes that the PKCS routine checks the format of the key. */
743 silc_pkcs_alloc(pkcs_name, &alg);
744 if (!alg->pkcs->set_private_key(alg->context, key_data, key_len))
749 *private_key = silc_calloc(1, sizeof(**private_key));
750 (*private_key)->name = pkcs_name;
751 (*private_key)->prv = key_data;
752 (*private_key)->prv_len = key_len;
755 silc_buffer_free(buf);
760 silc_free(pkcs_name);
763 silc_buffer_free(buf);
767 /* Internal routine to save public key */
769 static int silc_pkcs_save_public_key_internal(char *filename,
778 case SILC_PKCS_FILE_BIN:
780 case SILC_PKCS_FILE_PEM:
781 data = silc_encode_pem_file(data, data_len);
782 data_len = strlen(data);
786 len = data_len + (strlen(SILC_PKCS_PUBLIC_KEYFILE_BEGIN) +
787 strlen(SILC_PKCS_PUBLIC_KEYFILE_END));
788 buf = silc_buffer_alloc(len);
789 silc_buffer_pull_tail(buf, SILC_BUFFER_END(buf));
791 silc_buffer_format(buf,
792 SILC_STR_UI32_STRING(SILC_PKCS_PUBLIC_KEYFILE_BEGIN),
793 SILC_STR_UI_XNSTRING(data, data_len),
794 SILC_STR_UI32_STRING(SILC_PKCS_PUBLIC_KEYFILE_END),
798 if (silc_file_write(filename, buf->data, buf->len)) {
799 silc_buffer_free(buf);
803 silc_buffer_free(buf);
807 /* Saves public key into file */
809 int silc_pkcs_save_public_key(char *filename, SilcPublicKey public_key,
815 data = silc_pkcs_public_key_encode(public_key, &data_len);
816 return silc_pkcs_save_public_key_internal(filename, data, data_len,
820 /* Saves public key into file */
822 int silc_pkcs_save_public_key_data(char *filename, unsigned char *data,
826 return silc_pkcs_save_public_key_internal(filename, data, data_len,
830 /* Internal routine to save private key. */
832 static int silc_pkcs_save_private_key_internal(char *filename,
841 case SILC_PKCS_FILE_BIN:
843 case SILC_PKCS_FILE_PEM:
844 data = silc_encode_pem_file(data, data_len);
845 data_len = strlen(data);
849 len = data_len + (strlen(SILC_PKCS_PRIVATE_KEYFILE_BEGIN) +
850 strlen(SILC_PKCS_PRIVATE_KEYFILE_END));
851 buf = silc_buffer_alloc(len);
852 silc_buffer_pull_tail(buf, SILC_BUFFER_END(buf));
854 silc_buffer_format(buf,
855 SILC_STR_UI32_STRING(SILC_PKCS_PRIVATE_KEYFILE_BEGIN),
856 SILC_STR_UI_XNSTRING(data, data_len),
857 SILC_STR_UI32_STRING(SILC_PKCS_PRIVATE_KEYFILE_END),
860 /* Save into a file */
861 if (silc_file_write_mode(filename, buf->data, buf->len, 0600)) {
862 silc_buffer_free(buf);
866 silc_buffer_free(buf);
870 /* Saves private key into file. */
871 /* XXX The buffer should be encrypted if passphrase is provided. */
873 int silc_pkcs_save_private_key(char *filename, SilcPrivateKey private_key,
874 unsigned char *passphrase,
880 data = silc_pkcs_private_key_encode(private_key, &data_len);
881 return silc_pkcs_save_private_key_internal(filename, data, data_len,
885 /* Saves private key into file. */
886 /* XXX The buffer should be encrypted if passphrase is provided. */
888 int silc_pkcs_save_private_key_data(char *filename, unsigned char *data,
890 unsigned char *passphrase,
893 return silc_pkcs_save_private_key_internal(filename, data, data_len,
897 /* Loads public key from file and allocates new public key. Returns TRUE
898 is loading was successful. */
900 int silc_pkcs_load_public_key(char *filename, SilcPublicKey *public_key,
903 unsigned char *cp, *old, *data, byte;
904 uint32 i, data_len, len;
906 old = data = silc_file_read(filename, &data_len);
910 /* Check start of file and remove header from the data. */
911 len = strlen(SILC_PKCS_PUBLIC_KEYFILE_BEGIN);
913 for (i = 0; i < len; i++) {
916 if (byte != SILC_PKCS_PUBLIC_KEYFILE_BEGIN[i]) {
917 memset(old, 0, data_len);
924 /* Decode public key */
926 len = data_len - (strlen(SILC_PKCS_PUBLIC_KEYFILE_BEGIN) +
927 strlen(SILC_PKCS_PUBLIC_KEYFILE_END));
930 case SILC_PKCS_FILE_BIN:
932 case SILC_PKCS_FILE_PEM:
933 data = silc_decode_pem(data, len, &len);
937 if (!data || !silc_pkcs_public_key_decode(data, len, public_key)) {
938 memset(old, 0, data_len);
944 memset(old, 0, data_len);
949 /* Load private key from file and allocates new private key. Returns TRUE
950 if loading was successful. */
951 /* XXX Should support encrypted private key files */
953 int silc_pkcs_load_private_key(char *filename, SilcPrivateKey *private_key,
956 unsigned char *cp, *old, *data, byte;
957 uint32 i, data_len, len;
959 old = data = silc_file_read(filename, &data_len);
963 /* Check start of file and remove header from the data. */
964 len = strlen(SILC_PKCS_PRIVATE_KEYFILE_BEGIN);
966 for (i = 0; i < len; i++) {
969 if (byte != SILC_PKCS_PRIVATE_KEYFILE_BEGIN[i]) {
970 memset(old, 0, data_len);
977 /* Decode private key */
979 len = data_len - (strlen(SILC_PKCS_PRIVATE_KEYFILE_BEGIN) +
980 strlen(SILC_PKCS_PRIVATE_KEYFILE_END));
983 case SILC_PKCS_FILE_BIN:
985 case SILC_PKCS_FILE_PEM:
986 data = silc_decode_pem(data, len, &len);
990 if (!data || !silc_pkcs_private_key_decode(data, len, private_key)) {
991 memset(old, 0, data_len);
997 memset(old, 0, data_len);