- /* Check start of file and remove header from the data. */
- len = strlen(SILC_PKCS_PUBLIC_KEYFILE_BEGIN);
- cp = data;
- for (i = 0; i < len; i++) {
- byte = cp[0];
- cp++;
- if (byte != SILC_PKCS_PUBLIC_KEYFILE_BEGIN[i]) {
- memset(old, 0, data_len);
- silc_free(old);
- return FALSE;
- }
- }
- data = cp;
-
- /* Decode public key */
- if (public_key) {
- len = data_len - (strlen(SILC_PKCS_PUBLIC_KEYFILE_BEGIN) +
- strlen(SILC_PKCS_PUBLIC_KEYFILE_END));
-
- switch(encoding) {
- case SILC_PKCS_FILE_BIN:
- break;
- case SILC_PKCS_FILE_PEM:
- data = silc_pem_decode(data, len, &len);
- memset(old, 0, data_len);
- silc_free(old);
- old = data;
- data_len = len;
- break;
- }
-
- if (!data || !silc_pkcs_public_key_decode(data, len, public_key)) {
- memset(old, 0, data_len);
- silc_free(old);
- return FALSE;
- }
- }
-
- memset(old, 0, data_len);
- silc_free(old);
- return TRUE;
-}
-
-/* Load private key from file and allocates new private key. Returns TRUE
- if loading was successful. */
-
-bool silc_pkcs_load_private_key(const char *filename,
- SilcPrivateKey *private_key,
- unsigned char *passphrase,
- SilcUInt32 passphrase_len,
- SilcUInt32 encoding)
-{
- SilcCipher aes;
- SilcHash sha1;
- SilcHmac sha1hmac;
- SilcUInt32 blocklen;
- unsigned char tmp[32], keymat[64];
- unsigned char *cp, *old, *data, byte;
- SilcUInt32 i, data_len, len, magic, mac_len;
-
- SILC_LOG_DEBUG(("Loading private key `%s' with %s encoding", filename,
- encoding == SILC_PKCS_FILE_PEM ? "Base64" :
- encoding == SILC_PKCS_FILE_BIN ? "Binary" : "Unkonwn"));
-
- old = data = silc_file_readfile(filename, &data_len);
- if (!data)
- return FALSE;
-
- /* Check start of file and remove header from the data. */
- len = strlen(SILC_PKCS_PRIVATE_KEYFILE_BEGIN);
- cp = data;
- for (i = 0; i < len; i++) {
- byte = cp[0];
- cp++;
- if (byte != SILC_PKCS_PRIVATE_KEYFILE_BEGIN[i]) {
- memset(old, 0, data_len);
- silc_free(old);
- return FALSE;
- }
- }
- data = cp;
-
- /* Decode private key */
- len = data_len - (strlen(SILC_PKCS_PRIVATE_KEYFILE_BEGIN) +
- strlen(SILC_PKCS_PRIVATE_KEYFILE_END));
-
- switch(encoding) {
- case SILC_PKCS_FILE_BIN:
- break;
- case SILC_PKCS_FILE_PEM:
- data = silc_pem_decode(data, len, &len);
- if (!data) {
- memset(old, 0, data_len);
- silc_free(old);
- return FALSE;
- }
- break;
- }
-
- memset(tmp, 0, sizeof(tmp));
- memset(keymat, 0, sizeof(keymat));
-
- /* Private key files without the specific magic number are assumed
- to be the old-style private keys that are not encrypted. */
- SILC_GET32_MSB(magic, data);
- if (magic != SILC_PKCS_PRIVATE_KEY_MAGIC) {
- SILC_LOG_DEBUG(("Private key does not have correct magic!"));
-
- /* Now decode the actual private key */
- if (!silc_pkcs_private_key_decode(data, len, private_key)) {
- memset(old, 0, data_len);
- silc_free(old);
- return FALSE;
- }
-
- memset(old, 0, data_len);
- silc_free(old);
- return TRUE;
- }
-
- /* Allocate the AES cipher */
- if (!silc_cipher_alloc("aes-256-cbc", &aes)) {
- SILC_LOG_ERROR(("Could not allocate AES cipher, probably not registered"));
- memset(old, 0, data_len);
- silc_free(old);
- return FALSE;
- }
- blocklen = silc_cipher_get_block_len(aes);
- if (blocklen * 2 > sizeof(tmp)) {
- memset(old, 0, data_len);
- silc_free(old);
- return FALSE;
- }
-
- /* Allocate SHA1 hash */
- if (!silc_hash_alloc("sha1", &sha1)) {
- SILC_LOG_ERROR(("Could not allocate SHA1 hash, probably not registered"));
- silc_cipher_free(aes);
- memset(old, 0, data_len);
- silc_free(old);