RSA *rsa;
};
+static int openssl_perror(const char *pfx)
+{
+ unsigned long err = ERR_get_error();
+ PARA_ERROR_LOG("%s: \"%s\"\n", pfx, ERR_reason_error_string(err));
+ return -E_OPENSSL;
+}
+
void get_random_bytes_or_die(unsigned char *buf, int num)
{
- unsigned long err;
+ int ret;
- /* RAND_bytes() returns 1 on success, 0 otherwise. */
- if (RAND_bytes(buf, num) == 1)
+ if (RAND_bytes(buf, num) == 1) /* success */
return;
- err = ERR_get_error();
- PARA_EMERG_LOG("%s\n", ERR_reason_error_string(err));
+ ret = openssl_perror("RAND_bytes");
+ PARA_EMERG_LOG("%s\n", strerror(-ret));
exit(EXIT_FAILURE);
}
/*
- * Read 64 bytes from /dev/urandom and add them to the SSL PRNG. Seed the PRNG
- * used by random(3) with a random seed obtained from SSL. If /dev/urandom is
- * not readable, the function calls exit().
- *
- * \sa RAND_load_file(3), \ref get_random_bytes_or_die(), srandom(3),
- * random(3), \ref para_random().
+ * Read 64 bytes from /dev/urandom and add them to the SSL PRNG. Then seed the
+ * PRNG used by random(3) with a random seed obtained from SSL.
*/
void crypt_init(void)
{
return bnsize + 4;
}
-static int read_rsa_bignums(const unsigned char *blob, int blen, RSA **result)
+static int read_public_key(const unsigned char *blob, int blen,
+ struct asymmetric_key *result)
{
int ret;
RSA *rsa;
BIGNUM *n, *e;
const unsigned char *p = blob, *end = blob + blen;
- rsa = RSA_new();
- if (!rsa)
- return -E_BIGNUM;
+ assert((rsa = RSA_new()));
ret = read_bignum(p, end - p, &e);
if (ret < 0)
goto free_rsa;
rsa->n = n;
rsa->e = e;
#endif
- *result = rsa;
+ result->rsa = rsa;
return 1;
free_e:
BN_free(e);
return ret;
}
-static int read_pem_private_key(const char *path, RSA **rsa)
+static int read_pem_private_key(const char *path, struct asymmetric_key *priv)
{
EVP_PKEY *pkey;
- BIO *bio = BIO_new(BIO_s_file());
+ BIO *bio;
- *rsa = NULL;
- if (!bio)
- return -E_PRIVATE_KEY;
+ assert((bio = BIO_new(BIO_s_file())));
+ priv->rsa = NULL;
if (BIO_read_filename(bio, path) <= 0)
goto bio_free;
pkey = PEM_read_bio_PrivateKey(bio, NULL, NULL, NULL);
if (!pkey)
goto bio_free;
- *rsa = EVP_PKEY_get1_RSA(pkey);
+ priv->rsa = EVP_PKEY_get1_RSA(pkey);
EVP_PKEY_free(pkey);
bio_free:
BIO_free(bio);
- return *rsa? RSA_size(*rsa) : -E_PRIVATE_KEY;
+ return priv->rsa? RSA_size(priv->rsa) : -E_PRIVATE_KEY;
}
-static int read_private_rsa_params(const unsigned char *blob,
- const unsigned char *end, RSA **result)
+static int read_openssh_private_key(const unsigned char *blob,
+ const unsigned char *end, struct asymmetric_key *priv)
{
int ret;
RSA *rsa;
- BN_CTX *ctx;
BIGNUM *n, *e, *d, *iqmp, *p, *q; /* stored in the key file */
- BIGNUM *dmp1, *dmq1; /* these will be computed */
- BIGNUM *tmp;
const unsigned char *cp = blob;
- rsa = RSA_new();
- if (!rsa)
- return -E_BIGNUM;
- ret = -E_BIGNUM;
- tmp = BN_new();
- if (!tmp)
- goto free_rsa;
- ctx = BN_CTX_new();
- if (!ctx)
- goto free_tmp;
- dmp1 = BN_new();
- if (!dmp1)
- goto free_ctx;
- dmq1 = BN_new();
- if (!dmq1)
- goto free_dmp1;
+ assert((rsa = RSA_new()));
ret = read_bignum(cp, end - cp, &n);
if (ret < 0)
- goto free_dmq1;
+ goto free_rsa;
cp += ret;
ret = read_bignum(cp, end - cp, &e);
if (ret < 0)
ret = read_bignum(cp, end - cp, &q);
if (ret < 0)
goto free_p;
- ret = -E_BIGNUM;
- if (!BN_sub(tmp, q, BN_value_one()))
- goto free_q;
- if (!BN_mod(dmp1, d, tmp, ctx))
- goto free_q;
- if (!BN_sub(tmp, q, BN_value_one()))
- goto free_q;
- if (!BN_mod(dmq1, d, tmp, ctx))
- goto free_q;
#ifdef HAVE_RSA_SET0_KEY
RSA_set0_key(rsa, n, e, d);
RSA_set0_factors(rsa, p, q);
- RSA_set0_crt_params(rsa, dmp1, dmq1, iqmp);
+ RSA_set0_crt_params(rsa, NULL, NULL, iqmp);
+
#else
rsa->n = n;
rsa->e = e;
rsa->d = d;
+ rsa->iqmp = iqmp;
rsa->p = p;
rsa->q = q;
- rsa->dmp1 = dmp1;
- rsa->dmq1 = dmq1;
- rsa->iqmp = iqmp;
#endif
- *result = rsa;
- ret = 1;
- goto free_ctx;
-free_q:
- BN_clear_free(q);
+ priv->rsa = rsa;
+ return 1;
free_p:
BN_clear_free(p);
free_iqmp:
BN_free(e);
free_n:
BN_free(n);
-free_dmq1:
- BN_clear_free(dmq1);
-free_dmp1:
- BN_clear_free(dmp1);
-free_ctx:
- BN_CTX_free(ctx);
-free_tmp:
- BN_clear_free(tmp);
free_rsa:
- if (ret < 0)
- RSA_free(rsa);
+ RSA_free(rsa);
return ret;
}
-static int get_private_key(const char *path, RSA **rsa)
+static int get_private_key(const char *path, struct asymmetric_key *priv)
{
int ret;
unsigned char *blob, *end;
size_t blob_size;
- *rsa = NULL;
+ priv->rsa = NULL;
ret = decode_private_key(path, &blob, &blob_size);
if (ret < 0)
return ret;
if (ret < 0)
goto free_blob;
PARA_INFO_LOG("reading RSA params at offset %d\n", ret);
- ret = read_private_rsa_params(blob + ret, end, rsa);
+ ret = read_openssh_private_key(blob + ret, end, priv);
} else
- ret = read_pem_private_key(path, rsa);
+ ret = read_pem_private_key(path, priv);
free_blob:
free(blob);
return ret;
unsigned char *blob;
size_t decoded_size;
int ret;
- struct asymmetric_key *key = alloc(sizeof(*key));
+ struct asymmetric_key *pub = alloc(sizeof(*pub));
ret = decode_public_key(key_file, &blob, &decoded_size);
if (ret < 0)
goto out;
- ret = read_rsa_bignums(blob + ret, decoded_size - ret, &key->rsa);
+ ret = read_public_key(blob + ret, decoded_size - ret, pub);
if (ret < 0)
goto free_blob;
- ret = RSA_size(key->rsa);
+ ret = RSA_size(pub->rsa);
assert(ret > 0);
- *result = key;
+ *result = pub;
free_blob:
free(blob);
out:
if (ret < 0) {
- free(key);
+ free(pub);
*result = NULL;
PARA_ERROR_LOG("can not load key %s\n", key_file);
}
return ret;
}
-void apc_free_pubkey(struct asymmetric_key *key)
+void apc_free_pubkey(struct asymmetric_key *pub)
{
- if (!key)
+ if (!pub)
return;
- RSA_free(key->rsa);
- free(key);
+ RSA_free(pub->rsa);
+ free(pub);
}
int apc_priv_decrypt(const char *key_file, unsigned char *outbuf,
if (inlen < 0)
return -E_RSA;
priv = alloc(sizeof(*priv));
- ret = get_private_key(key_file, &priv->rsa);
+ ret = get_private_key(key_file, priv);
if (ret < 0) {
free(priv);
return ret;
struct stream_cipher *sc = alloc(sizeof(*sc));
assert(len >= 2 * AES_CRT128_BLOCK_SIZE);
- sc->aes = EVP_CIPHER_CTX_new();
+ assert((sc->aes = EVP_CIPHER_CTX_new()));
EVP_EncryptInit_ex(sc->aes, EVP_aes_128_ctr(), NULL, data,
data + AES_CRT128_BLOCK_SIZE);
return sc;
void hash_function(const char *data, unsigned long len, unsigned char *hash)
{
- EVP_MD_CTX *c = EVP_MD_CTX_new();
- int ret = EVP_DigestInit_ex(c, EVP_sha1(), NULL);
+ int ret;
+ EVP_MD_CTX *c;
+
+ assert((c = EVP_MD_CTX_new()));
+ ret = EVP_DigestInit_ex(c, EVP_sha1(), NULL);
assert(ret != 0);
ret = EVP_DigestUpdate(c, data, len);
assert(ret != 0);
void hash2_function(const char *data, unsigned long len, unsigned char *hash)
{
- EVP_MD_CTX *c = EVP_MD_CTX_new();
- int ret = EVP_DigestInit_ex(c, EVP_sha256(), NULL);
+ int ret;
+ EVP_MD_CTX *c;
+
+ assert((c = EVP_MD_CTX_new()));
+ ret = EVP_DigestInit_ex(c, EVP_sha256(), NULL);
assert(ret != 0);
ret = EVP_DigestUpdate(c, data, len);
assert(ret != 0);