#include "crypt.h"
#include "fd.h"
#include "crypt_backend.h"
+#include "base64.h"
struct asymmetric_key {
RSA *rsa;
srandom(seed);
}
-static EVP_PKEY *load_key(const char *file, int private)
+static EVP_PKEY *load_key(const char *file)
{
BIO *key;
EVP_PKEY *pkey = NULL;
- int ret = check_key_file(file, private);
- if (ret < 0) {
- PARA_ERROR_LOG("%s\n", para_strerror(-ret));
- return NULL;
- }
key = BIO_new(BIO_s_file());
if (!key)
return NULL;
- if (BIO_read_filename(key, file) > 0) {
- if (private == LOAD_PRIVATE_KEY)
- pkey = PEM_read_bio_PrivateKey(key, NULL, NULL, NULL);
- else
- pkey = PEM_read_bio_PUBKEY(key, NULL, NULL, NULL);
- }
+ if (BIO_read_filename(key, file) > 0)
+ pkey = PEM_read_bio_PrivateKey(key, NULL, NULL, NULL);
BIO_free(key);
return pkey;
}
-static int get_openssl_key(const char *key_file, RSA **rsa, int private)
+static int get_private_key(const char *key_file, RSA **rsa)
{
- EVP_PKEY *key = load_key(key_file, private);
+ EVP_PKEY *key = load_key(key_file);
if (!key)
- return (private == LOAD_PRIVATE_KEY)? -E_PRIVATE_KEY
- : -E_PUBLIC_KEY;
+ return -E_PRIVATE_KEY;
*rsa = EVP_PKEY_get1_RSA(key);
EVP_PKEY_free(key);
if (!*rsa)
return ret;
}
-int get_asymmetric_key(const char *key_file, int private,
- struct asymmetric_key **result)
+int get_public_key(const char *key_file, struct asymmetric_key **result)
{
struct asymmetric_key *key = NULL;
void *map = NULL;
unsigned char *blob = NULL;
- size_t map_size, blob_size, decoded_size;
+ size_t map_size, encoded_size, decoded_size;
int ret, ret2;
char *cp;
key = para_malloc(sizeof(*key));
- if (private) {
- ret = get_openssl_key(key_file, &key->rsa, LOAD_PRIVATE_KEY);
- goto out;
- }
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) {
- ret = para_munmap(map, map_size);
- map = NULL;
- if (ret < 0)
- goto out;
- ret = get_openssl_key(key_file, &key->rsa, LOAD_PUBLIC_KEY);
- goto out;
+ 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 = -ERRNO_TO_PARA_ERROR(EOVERFLOW);
- if (map_size > INT_MAX / 4)
- goto out_unmap;
- blob_size = 2 * map_size;
- blob = para_malloc(blob_size);
- ret = uudecode(cp, blob, blob_size);
+ ret = uudecode(cp, encoded_size, (char **)&blob, &decoded_size);
if (ret < 0)
goto out_unmap;
- decoded_size = ret;
ret = check_ssh_key_header(blob, decoded_size);
if (ret < 0)
goto out_unmap;
return ret;
}
-void free_asymmetric_key(struct asymmetric_key *key)
+void free_public_key(struct asymmetric_key *key)
{
if (!key)
return;
struct asymmetric_key *priv;
int ret;
+ ret = check_private_key_file(key_file);
+ if (ret < 0)
+ return ret;
if (inlen < 0)
return -E_RSA;
- ret = get_asymmetric_key(key_file, LOAD_PRIVATE_KEY, &priv);
- if (ret < 0)
+ priv = para_malloc(sizeof(*priv));
+ ret = get_private_key(key_file, &priv->rsa);
+ if (ret < 0) {
+ free(priv);
return ret;
+ }
/*
* RSA is vulnerable to timing attacks. Generate a random blinding
* factor to protect against this kind of attack.
if (ret <= 0)
ret = -E_DECRYPT;
out:
- free_asymmetric_key(priv);
+ RSA_free(priv->rsa);
+ free(priv);
return ret;
}