/* Hash all multi precision integers of the key PK with the given message digest context MD. */ static int hash_mpibuf (cdk_pubkey_t pk, digest_hd_st * md, int usefpr) { byte buf[MAX_MPI_BYTES]; /* FIXME: do not use hardcoded length. */ size_t nbytes; size_t i, npkey; int err; /* We have to differ between two modes for v3 keys. To form the fingerprint, we hash the MPI values without the length prefix. But if we calculate the hash for verifying/signing we use all data. */ npkey = cdk_pk_get_npkey (pk->pubkey_algo); for (i = 0; i < npkey; i++) { nbytes = MAX_MPI_BYTES; err = _gnutls_mpi_print_pgp (pk->mpi[i], buf, &nbytes); if (err < 0) return map_gnutls_error (err); if (!usefpr || pk->version == 4) _gnutls_hash (md, buf, nbytes); else /* without the prefix. */ _gnutls_hash (md, buf + 2, nbytes - 2); } return 0; }
static u16 checksum_mpi(bigint_t m) { byte buf[MAX_MPI_BYTES + 2]; size_t nread; unsigned int i; u16 chksum = 0; if (!m) return 0; nread = DIM(buf); if (_gnutls_mpi_print_pgp(m, buf, &nread) < 0) return 0; for (i = 0; i < nread; i++) chksum += buf[i]; return chksum; }
static int write_mpi (cdk_stream_t out, bigint_t m) { byte buf[MAX_MPI_BYTES + 2]; size_t nbits, nread; int err; if (!out || !m) return CDK_Inv_Value; nbits = _gnutls_mpi_get_nbits (m); if (nbits > MAX_MPI_BITS || nbits < 1) return CDK_MPI_Error; nread = MAX_MPI_BYTES + 2; err = _gnutls_mpi_print_pgp (m, buf, &nread); if (err < 0) return map_gnutls_error (err); return stream_write (out, buf, nread); }