return p - data;
}
+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;
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;
+ unsigned bits;
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");
- 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)
goto free_blob;
- }
- 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)
goto release_e;
- }
- 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,
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;
+ ret = bits;
release_n:
gcry_mpi_release(n);
release_e: