This functionality was open-coded twice in apc_get_pubkey() which
reads the two public rsa params. Use the new function instead to
get rid of the duplication. It will be turn out to be useful for
the subsequent work which adds support for RFC4716 keys. Since the
function is specific to libgcrypt, it has to stay in gcrypt.c.
+static int read_openssh_bignum(unsigned char *start, unsigned char *end,
+ gcry_mpi_t *bn, unsigned *bitsp)
+{
+ gcry_error_t gret;
+ size_t nscanned;
+ unsigned bits;
+
+ gret = gcry_mpi_scan(bn, GCRYMPI_FMT_SSH, start, end - start, &nscanned);
+ if (gret) {
+ PARA_ERROR_LOG("gcry_mpi_scan: %s\n",
+ gcry_strerror(gcry_err_code(gret)));
+ return -E_MPI_SCAN;
+ }
+ bits = (nscanned - 4 - (start[4] == '\0')) * 8;
+ if (bitsp)
+ *bitsp = bits;
+ PARA_DEBUG_LOG("scanned %u-bit bignum\n", bits);
+ return nscanned;
+}
+
static int get_private_key(const char *key_file, struct asymmetric_key **result)
{
struct rsa_params params;
static int get_private_key(const char *key_file, struct asymmetric_key **result)
{
struct rsa_params params;
unsigned char *blob, *p, *end;
int ret;
gcry_error_t gret;
unsigned char *blob, *p, *end;
int ret;
gcry_error_t gret;
- size_t nr_scanned, erroff, decoded_size;
+ size_t erroff, decoded_size;
gcry_mpi_t e, n;
gcry_sexp_t sexp;
struct asymmetric_key *key;
gcry_mpi_t e, n;
gcry_sexp_t sexp;
struct asymmetric_key *key;
ret = decode_ssh_key(key_file, &blob, &decoded_size);
if (ret < 0)
ret = decode_ssh_key(key_file, &blob, &decoded_size);
if (ret < 0)
p = blob + ret;
end = blob + decoded_size;
PARA_DEBUG_LOG("scanning modulus and public exponent\n");
p = blob + ret;
end = blob + decoded_size;
PARA_DEBUG_LOG("scanning modulus and public exponent\n");
- gret = gcry_mpi_scan(&e, GCRYMPI_FMT_SSH, p, end - p, &nr_scanned);
- if (gret) {
- ret = -E_MPI_SCAN;
- PARA_CRIT_LOG("%s\n", gcry_strerror(gcry_err_code(gret)));
+ ret = read_openssh_bignum(p, end, &e, NULL);
+ if (ret < 0)
- }
- PARA_DEBUG_LOG("scanned e (%zu bytes)\n", nr_scanned);
- p += nr_scanned;
- if (p >= end)
- goto release_e;
- gret = gcry_mpi_scan(&n, GCRYMPI_FMT_SSH, p, end - p, &nr_scanned);
- if (gret) {
- ret = -E_MPI_SCAN;
- PARA_ERROR_LOG("%s\n", gcry_strerror(gcry_err_code(gret)));
+ p += ret;
+ ret = read_openssh_bignum(p, end, &n, &bits);
+ if (ret < 0)
- }
- PARA_DEBUG_LOG("scanned n (%zu bytes)\n", nr_scanned);
gret = gcry_sexp_build(&sexp, &erroff, RSA_PUBKEY_SEXP, n, e);
if (gret) {
PARA_ERROR_LOG("offset %zu: %s\n", erroff,
gret = gcry_sexp_build(&sexp, &erroff, RSA_PUBKEY_SEXP, n, e);
if (gret) {
PARA_ERROR_LOG("offset %zu: %s\n", erroff,
ret = -E_SEXP_BUILD;
goto release_n;
}
ret = -E_SEXP_BUILD;
goto release_n;
}
- ret = ROUND_DOWN(nr_scanned, 32);
- PARA_INFO_LOG("successfully read %d bit ssh public key\n", ret * 8);
+ PARA_INFO_LOG("successfully read %u bit ssh public key\n", bits);
key = para_malloc(sizeof(*key));
key->num_bytes = ret;
key->sexp = sexp;
*result = key;
key = para_malloc(sizeof(*key));
key->num_bytes = ret;
key->sexp = sexp;
*result = key;
release_n:
gcry_mpi_release(n);
release_e:
release_n:
gcry_mpi_release(n);
release_e: