Function: gnutls-hash-digest
gnutls-hash-digest is a function defined in gnutls.c.
Signature
(gnutls-hash-digest DIGEST-METHOD INPUT)
Documentation
Digest INPUT with DIGEST-METHOD into a unibyte string.
Return nil on error.
The INPUT can be specified as a buffer or string or in other ways (see Info node (elisp)Format of GnuTLS Cryptography Inputs).
The alist of digest algorithms can be obtained with gnutls-digests.
The DIGEST-METHOD may be a string or symbol matching a key in that
alist, or a plist with the :digest-algorithm-id numeric property, or
the number itself.
Probably introduced at or before Emacs version 26.1.
Source Code
// Defined in /usr/src/emacs/src/gnutls.c
{
if (BUFFERP (input) || STRINGP (input))
input = list1 (input);
CHECK_CONS (input);
gnutls_digest_algorithm_t gda = GNUTLS_DIG_UNKNOWN;
Lisp_Object info = Qnil;
if (STRINGP (digest_method))
digest_method = intern (SSDATA (digest_method));
if (SYMBOLP (digest_method))
{
info = Fassq (digest_method, Fgnutls_digests ());
if (!CONSP (info))
xsignal2 (Qerror,
build_string ("GnuTLS digest-method is invalid or not found"),
digest_method);
info = XCDR (info);
}
else if (TYPE_RANGED_FIXNUMP (gnutls_digest_algorithm_t, digest_method))
gda = XFIXNUM (digest_method);
else
info = digest_method;
if (!NILP (info) && CONSP (info))
{
Lisp_Object v = plist_get (info, QCdigest_algorithm_id);
if (TYPE_RANGED_FIXNUMP (gnutls_digest_algorithm_t, v))
gda = XFIXNUM (v);
}
ptrdiff_t digest_length = gnutls_hash_get_len (gda);
if (digest_length == 0)
xsignal2 (Qerror,
build_string ("GnuTLS digest-method is invalid or not found"),
digest_method);
gnutls_hash_hd_t hash;
int ret = gnutls_hash_init (&hash, gda);
if (ret < GNUTLS_E_SUCCESS)
error ("GnuTLS digest initialization failed: %s",
emacs_gnutls_strerror (ret));
Lisp_Object digest = make_uninit_string (digest_length);
ptrdiff_t istart_byte, iend_byte;
const char *idata
= extract_data_from_object (input, &istart_byte, &iend_byte);
if (idata == NULL)
error ("GnuTLS digest input extraction failed");
ret = gnutls_hash (hash, idata + istart_byte, iend_byte - istart_byte);
if (ret < GNUTLS_E_SUCCESS)
{
gnutls_hash_deinit (hash, NULL);
error ("GnuTLS digest application failed: %s",
emacs_gnutls_strerror (ret));
}
gnutls_hash_output (hash, SSDATA (digest));
gnutls_hash_deinit (hash, NULL);
return digest;
}