+ struct asymmetric_key *key = NULL;
+ void *map = NULL;
+ unsigned char *blob = NULL;
+ size_t map_size, encoded_size, decoded_size;
+ int ret, ret2;
+ char *cp;
+
+ key = para_malloc(sizeof(*key));
+ ret = mmap_full_file(key_file, O_RDONLY, &map, &map_size, NULL);
+ if (ret < 0)
+ goto out;
+ ret = is_ssh_rsa_key(map, map_size);
+ if (!ret) {
+ para_munmap(map, map_size);
+ return -E_SSH_PARSE;
+ }
+ cp = map + ret;
+ encoded_size = map_size - ret;
+ PARA_INFO_LOG("decoding public rsa-ssh key %s\n", key_file);
+ ret = uudecode(cp, encoded_size, (char **)&blob, &decoded_size);
+ if (ret < 0)
+ goto out_unmap;
+ ret = check_ssh_key_header(blob, decoded_size);
+ if (ret < 0)
+ goto out_unmap;
+ ret = read_rsa_bignums(blob + ret, decoded_size - ret, &key->rsa);
+ if (ret < 0)
+ goto out_unmap;
+ ret = RSA_size(key->rsa);
+out_unmap:
+ ret2 = para_munmap(map, map_size);
+ if (ret >= 0 && ret2 < 0)
+ ret = ret2;
+out:
+ if (ret < 0) {
+ free(key);
+ *result = NULL;
+ PARA_ERROR_LOG("key %s: %s\n", key_file, para_strerror(-ret));
+ } else
+ *result = key;
+ free(blob);
+ return ret;