diff options
| author | Paul Eggert | 2017-07-14 16:18:37 -0700 |
|---|---|---|
| committer | Paul Eggert | 2017-07-14 16:36:18 -0700 |
| commit | 05b8b866993b957f5fd575846cf8ea3035e60f7e (patch) | |
| tree | 7d25217ee1f4c409cb217c52a6bd152dda675b8a /src | |
| parent | 8b64a80a56c0e15d3313a45022ae60b33dbb4bff (diff) | |
| download | emacs-05b8b866993b957f5fd575846cf8ea3035e60f7e.tar.gz emacs-05b8b866993b957f5fd575846cf8ea3035e60f7e.zip | |
GnuTLS integer-overflow and style fixes
This tweaks the recently-added GnuTLS improvements so that
they avoid some integer-overflow problems and follow typical
Emacs style a bit better.
* configure.ac (HAVE_GNUTLS3_HMAC, HAVE_GNUTLS3_AEAD)
(HAVE_GNUTLS3_CIPHER): Use AC_CACHE_CHECK so that the
configure-time results are displayed.
* src/fns.c (extract_data_from_object): Return char *, not char
const *, since one gnutls caller wants a non-const pointer. Use
CONSP rather than !NILP when testing for conses. Use CAR_SAFE
instead of rolling our own code. Prefer signed types to unsigned
when either will do. Report problems for lengths out of range,
instead of silently mishandling them.
* src/gnutls.c (emacs_gnutls_strerror): New function, to simplify
callers. All callers of gnutls_sterror changed.
(Fgnutls_boot): Check for integers out of range rather than
silently truncating them.
(gnutls_symmetric_aead): Check for integer overflow in size
calculations.
(gnutls_symmetric_aead, Fgnutls_macs, Fgnutls_digests):
Prefer signed to unsigned integers where either will do.
(gnutls_symmetric_aead, gnutls_symmetric):
Work even if ptrdiff_t is wider than ‘long’.
(gnutls_symmetric, Fgnutls_hash_mac, Fgnutls_hash_digest):
Check for integer overflow in algorithm selection.
Diffstat (limited to 'src')
| -rw-r--r-- | src/fns.c | 49 | ||||
| -rw-r--r-- | src/gnutls.c | 489 | ||||
| -rw-r--r-- | src/lisp.h | 4 |
3 files changed, 237 insertions, 305 deletions
| @@ -46,10 +46,6 @@ static void sort_vector_copy (Lisp_Object, ptrdiff_t, | |||
| 46 | enum equal_kind { EQUAL_NO_QUIT, EQUAL_PLAIN, EQUAL_INCLUDING_PROPERTIES }; | 46 | enum equal_kind { EQUAL_NO_QUIT, EQUAL_PLAIN, EQUAL_INCLUDING_PROPERTIES }; |
| 47 | static bool internal_equal (Lisp_Object, Lisp_Object, | 47 | static bool internal_equal (Lisp_Object, Lisp_Object, |
| 48 | enum equal_kind, int, Lisp_Object); | 48 | enum equal_kind, int, Lisp_Object); |
| 49 | static Lisp_Object | ||
| 50 | secure_hash (Lisp_Object algorithm, Lisp_Object object, Lisp_Object start, | ||
| 51 | Lisp_Object end, Lisp_Object coding_system, Lisp_Object noerror, | ||
| 52 | Lisp_Object binary); | ||
| 53 | 49 | ||
| 54 | DEFUN ("identity", Fidentity, Sidentity, 1, 1, 0, | 50 | DEFUN ("identity", Fidentity, Sidentity, 1, 1, 0, |
| 55 | doc: /* Return the argument unchanged. */ | 51 | doc: /* Return the argument unchanged. */ |
| @@ -4767,29 +4763,24 @@ DEFUN ("secure-hash-algorithms", Fsecure_hash_algorithms, | |||
| 4767 | (BUFFER-OR-STRING-OR-SYMBOL START END CODING-SYSTEM NOERROR) which behave as | 4763 | (BUFFER-OR-STRING-OR-SYMBOL START END CODING-SYSTEM NOERROR) which behave as |
| 4768 | specified with `secure-hash' and in Info node | 4764 | specified with `secure-hash' and in Info node |
| 4769 | `(elisp)Format of GnuTLS Cryptography Inputs'. */ | 4765 | `(elisp)Format of GnuTLS Cryptography Inputs'. */ |
| 4770 | const char* | 4766 | char * |
| 4771 | extract_data_from_object (Lisp_Object spec, | 4767 | extract_data_from_object (Lisp_Object spec, |
| 4772 | ptrdiff_t *start_byte, | 4768 | ptrdiff_t *start_byte, |
| 4773 | ptrdiff_t *end_byte) | 4769 | ptrdiff_t *end_byte) |
| 4774 | { | 4770 | { |
| 4775 | ptrdiff_t size, start_char = 0, end_char = 0; | 4771 | Lisp_Object object = XCAR (spec); |
| 4776 | register EMACS_INT b, e; | ||
| 4777 | register struct buffer *bp; | ||
| 4778 | EMACS_INT temp; | ||
| 4779 | 4772 | ||
| 4780 | Lisp_Object object = XCAR (spec); | 4773 | if (CONSP (spec)) spec = XCDR (spec); |
| 4774 | Lisp_Object start = CAR_SAFE (spec); | ||
| 4781 | 4775 | ||
| 4782 | if (! NILP (spec)) spec = XCDR (spec); | 4776 | if (CONSP (spec)) spec = XCDR (spec); |
| 4783 | Lisp_Object start = (CONSP (spec)) ? XCAR (spec) : Qnil; | 4777 | Lisp_Object end = CAR_SAFE (spec); |
| 4784 | 4778 | ||
| 4785 | if (! NILP (spec)) spec = XCDR (spec); | 4779 | if (CONSP (spec)) spec = XCDR (spec); |
| 4786 | Lisp_Object end = (CONSP (spec)) ? XCAR (spec) : Qnil; | 4780 | Lisp_Object coding_system = CAR_SAFE (spec); |
| 4787 | 4781 | ||
| 4788 | if (! NILP (spec)) spec = XCDR (spec); | 4782 | if (CONSP (spec)) spec = XCDR (spec); |
| 4789 | Lisp_Object coding_system = (CONSP (spec)) ? XCAR (spec) : Qnil; | 4783 | Lisp_Object noerror = CAR_SAFE (spec); |
| 4790 | |||
| 4791 | if (! NILP (spec)) spec = XCDR (spec); | ||
| 4792 | Lisp_Object noerror = (CONSP (spec)) ? XCAR (spec) : Qnil; | ||
| 4793 | 4784 | ||
| 4794 | if (STRINGP (object)) | 4785 | if (STRINGP (object)) |
| 4795 | { | 4786 | { |
| @@ -4817,7 +4808,7 @@ extract_data_from_object (Lisp_Object spec, | |||
| 4817 | if (STRING_MULTIBYTE (object)) | 4808 | if (STRING_MULTIBYTE (object)) |
| 4818 | object = code_convert_string (object, coding_system, Qnil, 1, 0, 1); | 4809 | object = code_convert_string (object, coding_system, Qnil, 1, 0, 1); |
| 4819 | 4810 | ||
| 4820 | size = SCHARS (object); | 4811 | ptrdiff_t size = SCHARS (object), start_char, end_char; |
| 4821 | validate_subarray (object, start, end, size, &start_char, &end_char); | 4812 | validate_subarray (object, start, end, size, &start_char, &end_char); |
| 4822 | 4813 | ||
| 4823 | *start_byte = !start_char ? 0 : string_char_to_byte (object, start_char); | 4814 | *start_byte = !start_char ? 0 : string_char_to_byte (object, start_char); |
| @@ -4828,12 +4819,13 @@ extract_data_from_object (Lisp_Object spec, | |||
| 4828 | else if (BUFFERP (object)) | 4819 | else if (BUFFERP (object)) |
| 4829 | { | 4820 | { |
| 4830 | struct buffer *prev = current_buffer; | 4821 | struct buffer *prev = current_buffer; |
| 4822 | EMACS_INT b, e; | ||
| 4831 | 4823 | ||
| 4832 | record_unwind_current_buffer (); | 4824 | record_unwind_current_buffer (); |
| 4833 | 4825 | ||
| 4834 | CHECK_BUFFER (object); | 4826 | CHECK_BUFFER (object); |
| 4835 | 4827 | ||
| 4836 | bp = XBUFFER (object); | 4828 | struct buffer *bp = XBUFFER (object); |
| 4837 | set_buffer_internal (bp); | 4829 | set_buffer_internal (bp); |
| 4838 | 4830 | ||
| 4839 | if (NILP (start)) | 4831 | if (NILP (start)) |
| @@ -4853,7 +4845,11 @@ extract_data_from_object (Lisp_Object spec, | |||
| 4853 | } | 4845 | } |
| 4854 | 4846 | ||
| 4855 | if (b > e) | 4847 | if (b > e) |
| 4856 | temp = b, b = e, e = temp; | 4848 | { |
| 4849 | EMACS_INT temp = b; | ||
| 4850 | b = e; | ||
| 4851 | e = temp; | ||
| 4852 | } | ||
| 4857 | 4853 | ||
| 4858 | if (!(BEGV <= b && e <= ZV)) | 4854 | if (!(BEGV <= b && e <= ZV)) |
| 4859 | args_out_of_range (start, end); | 4855 | args_out_of_range (start, end); |
| @@ -4932,14 +4928,13 @@ extract_data_from_object (Lisp_Object spec, | |||
| 4932 | else if (EQ (object, Qiv_auto)) | 4928 | else if (EQ (object, Qiv_auto)) |
| 4933 | { | 4929 | { |
| 4934 | #ifdef HAVE_GNUTLS3 | 4930 | #ifdef HAVE_GNUTLS3 |
| 4935 | // Format: (iv-auto REQUIRED-LENGTH) | 4931 | /* Format: (iv-auto REQUIRED-LENGTH). */ |
| 4936 | 4932 | ||
| 4937 | if (! INTEGERP (start)) | 4933 | if (! NATNUMP (start)) |
| 4938 | error ("Without a length, iv-auto can't be used. See manual."); | 4934 | error ("Without a length, iv-auto can't be used. See manual."); |
| 4939 | else | 4935 | else |
| 4940 | { | 4936 | { |
| 4941 | /* Make sure the value of "start" doesn't change. */ | 4937 | EMACS_INT start_hold = XFASTINT (start); |
| 4942 | size_t start_hold = XUINT (start); | ||
| 4943 | object = make_uninit_string (start_hold); | 4938 | object = make_uninit_string (start_hold); |
| 4944 | gnutls_rnd (GNUTLS_RND_NONCE, SSDATA (object), start_hold); | 4939 | gnutls_rnd (GNUTLS_RND_NONCE, SSDATA (object), start_hold); |
| 4945 | 4940 | ||
| @@ -4971,7 +4966,7 @@ secure_hash (Lisp_Object algorithm, Lisp_Object object, Lisp_Object start, | |||
| 4971 | 4966 | ||
| 4972 | Lisp_Object spec = list5 (object, start, end, coding_system, noerror); | 4967 | Lisp_Object spec = list5 (object, start, end, coding_system, noerror); |
| 4973 | 4968 | ||
| 4974 | const char* input = extract_data_from_object (spec, &start_byte, &end_byte); | 4969 | const char *input = extract_data_from_object (spec, &start_byte, &end_byte); |
| 4975 | 4970 | ||
| 4976 | if (input == NULL) | 4971 | if (input == NULL) |
| 4977 | error ("secure_hash: failed to extract data from object, aborting!"); | 4972 | error ("secure_hash: failed to extract data from object, aborting!"); |
diff --git a/src/gnutls.c b/src/gnutls.c index 761fe7df3ac..5717b3075c1 100644 --- a/src/gnutls.c +++ b/src/gnutls.c | |||
| @@ -672,6 +672,13 @@ emacs_gnutls_read (struct Lisp_Process *proc, char *buf, ptrdiff_t nbyte) | |||
| 672 | } | 672 | } |
| 673 | } | 673 | } |
| 674 | 674 | ||
| 675 | static char const * | ||
| 676 | emacs_gnutls_strerror (int err) | ||
| 677 | { | ||
| 678 | char const *str = gnutls_strerror (err); | ||
| 679 | return str ? str : "unknown"; | ||
| 680 | } | ||
| 681 | |||
| 675 | /* Report a GnuTLS error to the user. | 682 | /* Report a GnuTLS error to the user. |
| 676 | Return true if the error code was successfully handled. */ | 683 | Return true if the error code was successfully handled. */ |
| 677 | static bool | 684 | static bool |
| @@ -680,7 +687,6 @@ emacs_gnutls_handle_error (gnutls_session_t session, int err) | |||
| 680 | int max_log_level = 0; | 687 | int max_log_level = 0; |
| 681 | 688 | ||
| 682 | bool ret; | 689 | bool ret; |
| 683 | const char *str; | ||
| 684 | 690 | ||
| 685 | /* TODO: use a Lisp_Object generated by gnutls_make_error? */ | 691 | /* TODO: use a Lisp_Object generated by gnutls_make_error? */ |
| 686 | if (err >= 0) | 692 | if (err >= 0) |
| @@ -692,9 +698,7 @@ emacs_gnutls_handle_error (gnutls_session_t session, int err) | |||
| 692 | 698 | ||
| 693 | /* TODO: use gnutls-error-fatalp and gnutls-error-string. */ | 699 | /* TODO: use gnutls-error-fatalp and gnutls-error-string. */ |
| 694 | 700 | ||
| 695 | str = gnutls_strerror (err); | 701 | char const *str = emacs_gnutls_strerror (err); |
| 696 | if (!str) | ||
| 697 | str = "unknown"; | ||
| 698 | 702 | ||
| 699 | if (gnutls_error_is_fatal (err)) | 703 | if (gnutls_error_is_fatal (err)) |
| 700 | { | 704 | { |
| @@ -708,11 +712,11 @@ emacs_gnutls_handle_error (gnutls_session_t session, int err) | |||
| 708 | #endif | 712 | #endif |
| 709 | 713 | ||
| 710 | GNUTLS_LOG2 (level, max_log_level, "fatal error:", str); | 714 | GNUTLS_LOG2 (level, max_log_level, "fatal error:", str); |
| 711 | ret = 0; | 715 | ret = false; |
| 712 | } | 716 | } |
| 713 | else | 717 | else |
| 714 | { | 718 | { |
| 715 | ret = 1; | 719 | ret = true; |
| 716 | 720 | ||
| 717 | switch (err) | 721 | switch (err) |
| 718 | { | 722 | { |
| @@ -900,7 +904,7 @@ usage: (gnutls-error-string ERROR) */) | |||
| 900 | if (! TYPE_RANGED_INTEGERP (int, err)) | 904 | if (! TYPE_RANGED_INTEGERP (int, err)) |
| 901 | return build_string ("Not an error symbol or code"); | 905 | return build_string ("Not an error symbol or code"); |
| 902 | 906 | ||
| 903 | return build_string (gnutls_strerror (XINT (err))); | 907 | return build_string (emacs_gnutls_strerror (XINT (err))); |
| 904 | } | 908 | } |
| 905 | 909 | ||
| 906 | DEFUN ("gnutls-deinit", Fgnutls_deinit, Sgnutls_deinit, 1, 1, 0, | 910 | DEFUN ("gnutls-deinit", Fgnutls_deinit, Sgnutls_deinit, 1, 1, 0, |
| @@ -1592,9 +1596,9 @@ one trustfile (usually a CA bundle). */) | |||
| 1592 | XPROCESS (proc)->gnutls_x509_cred = x509_cred; | 1596 | XPROCESS (proc)->gnutls_x509_cred = x509_cred; |
| 1593 | 1597 | ||
| 1594 | verify_flags = Fplist_get (proplist, QCverify_flags); | 1598 | verify_flags = Fplist_get (proplist, QCverify_flags); |
| 1595 | if (NUMBERP (verify_flags)) | 1599 | if (TYPE_RANGED_INTEGERP (unsigned int, verify_flags)) |
| 1596 | { | 1600 | { |
| 1597 | gnutls_verify_flags = XINT (verify_flags); | 1601 | gnutls_verify_flags = XFASTINT (verify_flags); |
| 1598 | GNUTLS_LOG (2, max_log_level, "setting verification flags"); | 1602 | GNUTLS_LOG (2, max_log_level, "setting verification flags"); |
| 1599 | } | 1603 | } |
| 1600 | else if (NILP (verify_flags)) | 1604 | else if (NILP (verify_flags)) |
| @@ -1818,39 +1822,32 @@ This function may also return `gnutls-e-again', or | |||
| 1818 | DEFUN ("gnutls-ciphers", Fgnutls_ciphers, Sgnutls_ciphers, 0, 0, 0, | 1822 | DEFUN ("gnutls-ciphers", Fgnutls_ciphers, Sgnutls_ciphers, 0, 0, 0, |
| 1819 | doc: /* Return alist of GnuTLS symmetric cipher descriptions as plists. | 1823 | doc: /* Return alist of GnuTLS symmetric cipher descriptions as plists. |
| 1820 | The alist key is the cipher name. */) | 1824 | The alist key is the cipher name. */) |
| 1821 | (void) | 1825 | (void) |
| 1822 | { | 1826 | { |
| 1823 | Lisp_Object ciphers = Qnil; | 1827 | Lisp_Object ciphers = Qnil; |
| 1824 | 1828 | ||
| 1825 | const gnutls_cipher_algorithm_t* gciphers = gnutls_cipher_list (); | 1829 | const gnutls_cipher_algorithm_t *gciphers = gnutls_cipher_list (); |
| 1826 | for (size_t pos = 0; gciphers[pos] != GNUTLS_CIPHER_NULL; pos++) | 1830 | for (ptrdiff_t pos = 0; gciphers[pos] != GNUTLS_CIPHER_NULL; pos++) |
| 1827 | { | 1831 | { |
| 1828 | const gnutls_cipher_algorithm_t gca = gciphers[pos]; | 1832 | gnutls_cipher_algorithm_t gca = gciphers[pos]; |
| 1829 | 1833 | Lisp_Object cipher_symbol = intern (gnutls_cipher_get_name (gca)); | |
| 1830 | Lisp_Object cp = listn (CONSTYPE_HEAP, 15, | 1834 | ptrdiff_t cipher_tag_size = gnutls_cipher_get_tag_size (gca); |
| 1831 | /* A symbol representing the cipher */ | 1835 | |
| 1832 | intern (gnutls_cipher_get_name (gca)), | 1836 | Lisp_Object cp |
| 1833 | /* The internally meaningful cipher ID */ | 1837 | = listn (CONSTYPE_HEAP, 15, cipher_symbol, |
| 1834 | QCcipher_id, | 1838 | QCcipher_id, make_number (gca), |
| 1835 | make_number (gca), | 1839 | QCtype, Qgnutls_type_cipher, |
| 1836 | /* The type (vs. other GnuTLS objects). */ | 1840 | QCcipher_aead_capable, cipher_tag_size == 0 ? Qnil : Qt, |
| 1837 | QCtype, | 1841 | QCcipher_tagsize, make_number (cipher_tag_size), |
| 1838 | Qgnutls_type_cipher, | 1842 | |
| 1839 | /* The tag size (nonzero means AEAD). */ | 1843 | QCcipher_blocksize, |
| 1840 | QCcipher_aead_capable, | 1844 | make_number (gnutls_cipher_get_block_size (gca)), |
| 1841 | (gnutls_cipher_get_tag_size (gca) == 0) ? Qnil : Qt, | 1845 | |
| 1842 | /* The tag size (nonzero means AEAD). */ | 1846 | QCcipher_keysize, |
| 1843 | QCcipher_tagsize, | 1847 | make_number (gnutls_cipher_get_key_size (gca)), |
| 1844 | make_number (gnutls_cipher_get_tag_size (gca)), | 1848 | |
| 1845 | /* The block size */ | 1849 | QCcipher_ivsize, |
| 1846 | QCcipher_blocksize, | 1850 | make_number (gnutls_cipher_get_iv_size (gca))); |
| 1847 | make_number (gnutls_cipher_get_block_size (gca)), | ||
| 1848 | /* The key size */ | ||
| 1849 | QCcipher_keysize, | ||
| 1850 | make_number (gnutls_cipher_get_key_size (gca)), | ||
| 1851 | /* IV size */ | ||
| 1852 | QCcipher_ivsize, | ||
| 1853 | make_number (gnutls_cipher_get_iv_size (gca))); | ||
| 1854 | 1851 | ||
| 1855 | ciphers = Fcons (cp, ciphers); | 1852 | ciphers = Fcons (cp, ciphers); |
| 1856 | } | 1853 | } |
| @@ -1861,36 +1858,35 @@ The alist key is the cipher name. */) | |||
| 1861 | static Lisp_Object | 1858 | static Lisp_Object |
| 1862 | gnutls_symmetric_aead (bool encrypting, gnutls_cipher_algorithm_t gca, | 1859 | gnutls_symmetric_aead (bool encrypting, gnutls_cipher_algorithm_t gca, |
| 1863 | Lisp_Object cipher, | 1860 | Lisp_Object cipher, |
| 1864 | const char* kdata, size_t ksize, | 1861 | const char *kdata, ptrdiff_t ksize, |
| 1865 | const char* vdata, size_t vsize, | 1862 | const char *vdata, ptrdiff_t vsize, |
| 1866 | const char* idata, size_t isize, | 1863 | const char *idata, ptrdiff_t isize, |
| 1867 | Lisp_Object aead_auth) | 1864 | Lisp_Object aead_auth) |
| 1868 | { | 1865 | { |
| 1869 | #ifdef HAVE_GNUTLS3_AEAD | 1866 | #ifdef HAVE_GNUTLS3_AEAD |
| 1870 | 1867 | ||
| 1871 | const char* desc = (encrypting ? "encrypt" : "decrypt"); | 1868 | const char *desc = encrypting ? "encrypt" : "decrypt"; |
| 1872 | int ret = GNUTLS_E_SUCCESS; | ||
| 1873 | Lisp_Object actual_iv = make_unibyte_string (vdata, vsize); | 1869 | Lisp_Object actual_iv = make_unibyte_string (vdata, vsize); |
| 1874 | 1870 | ||
| 1875 | gnutls_aead_cipher_hd_t acipher; | 1871 | gnutls_aead_cipher_hd_t acipher; |
| 1876 | gnutls_datum_t key_datum = { (unsigned char*) kdata, ksize }; | 1872 | gnutls_datum_t key_datum = { (unsigned char *) kdata, ksize }; |
| 1877 | ret = gnutls_aead_cipher_init (&acipher, gca, &key_datum); | 1873 | int ret = gnutls_aead_cipher_init (&acipher, gca, &key_datum); |
| 1878 | 1874 | ||
| 1879 | if (ret < GNUTLS_E_SUCCESS) | 1875 | if (ret < GNUTLS_E_SUCCESS) |
| 1880 | { | 1876 | error ("GnuTLS AEAD cipher %s/%s initialization failed: %s", |
| 1881 | const char* str = gnutls_strerror (ret); | 1877 | gnutls_cipher_get_name (gca), desc, emacs_gnutls_strerror (ret)); |
| 1882 | if (!str) | 1878 | |
| 1883 | str = "unknown"; | 1879 | ptrdiff_t cipher_tag_size = gnutls_cipher_get_tag_size (gca); |
| 1884 | error ("GnuTLS AEAD cipher %s/%s initialization failed: %s", | 1880 | ptrdiff_t tagged_size; |
| 1885 | gnutls_cipher_get_name (gca), desc, str); | 1881 | if (INT_ADD_WRAPV (isize, cipher_tag_size, &tagged_size) |
| 1886 | } | 1882 | || SIZE_MAX < tagged_size) |
| 1887 | 1883 | memory_full (SIZE_MAX); | |
| 1888 | size_t storage_length = isize + gnutls_cipher_get_tag_size (gca); | 1884 | size_t storage_length = tagged_size; |
| 1889 | USE_SAFE_ALLOCA; | 1885 | USE_SAFE_ALLOCA; |
| 1890 | unsigned char *storage = SAFE_ALLOCA (storage_length); | 1886 | char *storage = SAFE_ALLOCA (storage_length); |
| 1891 | 1887 | ||
| 1892 | const char* aead_auth_data = NULL; | 1888 | const char *aead_auth_data = NULL; |
| 1893 | size_t aead_auth_size = 0; | 1889 | ptrdiff_t aead_auth_size = 0; |
| 1894 | 1890 | ||
| 1895 | if (!NILP (aead_auth)) | 1891 | if (!NILP (aead_auth)) |
| 1896 | { | 1892 | { |
| @@ -1900,8 +1896,8 @@ gnutls_symmetric_aead (bool encrypting, gnutls_cipher_algorithm_t gca, | |||
| 1900 | CHECK_CONS (aead_auth); | 1896 | CHECK_CONS (aead_auth); |
| 1901 | 1897 | ||
| 1902 | ptrdiff_t astart_byte, aend_byte; | 1898 | ptrdiff_t astart_byte, aend_byte; |
| 1903 | const char* adata = extract_data_from_object (aead_auth, &astart_byte, &aend_byte); | 1899 | const char *adata |
| 1904 | 1900 | = extract_data_from_object (aead_auth, &astart_byte, &aend_byte); | |
| 1905 | if (adata == NULL) | 1901 | if (adata == NULL) |
| 1906 | error ("GnuTLS AEAD cipher auth extraction failed"); | 1902 | error ("GnuTLS AEAD cipher auth extraction failed"); |
| 1907 | 1903 | ||
| @@ -1909,53 +1905,38 @@ gnutls_symmetric_aead (bool encrypting, gnutls_cipher_algorithm_t gca, | |||
| 1909 | aead_auth_size = aend_byte - astart_byte; | 1905 | aead_auth_size = aend_byte - astart_byte; |
| 1910 | } | 1906 | } |
| 1911 | 1907 | ||
| 1912 | size_t expected_remainder = 0; | 1908 | ptrdiff_t expected_remainder = encrypting ? 0 : cipher_tag_size; |
| 1913 | 1909 | ptrdiff_t cipher_block_size = gnutls_cipher_get_block_size (gca); | |
| 1914 | if (!encrypting) | ||
| 1915 | expected_remainder = gnutls_cipher_get_tag_size (gca); | ||
| 1916 | 1910 | ||
| 1917 | if ((isize - expected_remainder) % gnutls_cipher_get_block_size (gca) != 0) | 1911 | if (isize < expected_remainder |
| 1918 | error ("GnuTLS AEAD cipher %s/%s input block length %ld was not a " | 1912 | || (isize - expected_remainder) % cipher_block_size != 0) |
| 1919 | "multiple of the required %ld plus the expected tag remainder %ld", | 1913 | error (("GnuTLS AEAD cipher %s/%s input block length %"pD"d " |
| 1914 | "is not %"pD"d greater than a multiple of the required %"pD"d"), | ||
| 1920 | gnutls_cipher_get_name (gca), desc, | 1915 | gnutls_cipher_get_name (gca), desc, |
| 1921 | (long) isize, (long) gnutls_cipher_get_block_size (gca), | 1916 | isize, expected_remainder, cipher_block_size); |
| 1922 | (long) expected_remainder); | 1917 | |
| 1923 | 1918 | ret = ((encrypting ? gnutls_aead_cipher_encrypt : gnutls_aead_cipher_decrypt) | |
| 1924 | if (encrypting) | 1919 | (acipher, vdata, vsize, aead_auth_data, aead_auth_size, |
| 1925 | ret = gnutls_aead_cipher_encrypt (acipher, | 1920 | cipher_tag_size, idata, isize, storage, &storage_length)); |
| 1926 | vdata, vsize, | ||
| 1927 | aead_auth_data, aead_auth_size, | ||
| 1928 | gnutls_cipher_get_tag_size (gca), | ||
| 1929 | idata, isize, | ||
| 1930 | storage, &storage_length); | ||
| 1931 | else | ||
| 1932 | ret = gnutls_aead_cipher_decrypt (acipher, | ||
| 1933 | vdata, vsize, | ||
| 1934 | aead_auth_data, aead_auth_size, | ||
| 1935 | gnutls_cipher_get_tag_size (gca), | ||
| 1936 | idata, isize, | ||
| 1937 | storage, &storage_length); | ||
| 1938 | 1921 | ||
| 1939 | if (ret < GNUTLS_E_SUCCESS) | 1922 | if (ret < GNUTLS_E_SUCCESS) |
| 1940 | { | 1923 | { |
| 1941 | memset (storage, 0, storage_length); | 1924 | memset (storage, 0, storage_length); |
| 1942 | SAFE_FREE (); | 1925 | SAFE_FREE (); |
| 1943 | gnutls_aead_cipher_deinit (acipher); | 1926 | gnutls_aead_cipher_deinit (acipher); |
| 1944 | const char* str = gnutls_strerror (ret); | ||
| 1945 | if (!str) | ||
| 1946 | str = "unknown"; | ||
| 1947 | error ("GnuTLS AEAD cipher %s %sion failed: %s", | 1927 | error ("GnuTLS AEAD cipher %s %sion failed: %s", |
| 1948 | gnutls_cipher_get_name (gca), desc, str); | 1928 | gnutls_cipher_get_name (gca), desc, emacs_gnutls_strerror (ret)); |
| 1949 | } | 1929 | } |
| 1950 | 1930 | ||
| 1951 | gnutls_aead_cipher_deinit (acipher); | 1931 | gnutls_aead_cipher_deinit (acipher); |
| 1952 | 1932 | ||
| 1953 | Lisp_Object output = make_unibyte_string ((const char *)storage, storage_length); | 1933 | Lisp_Object output = make_unibyte_string (storage, storage_length); |
| 1954 | memset (storage, 0, storage_length); | 1934 | memset (storage, 0, storage_length); |
| 1955 | SAFE_FREE (); | 1935 | SAFE_FREE (); |
| 1956 | return list2 (output, actual_iv); | 1936 | return list2 (output, actual_iv); |
| 1957 | #else | 1937 | #else |
| 1958 | error ("GnuTLS AEAD cipher %ld was invalid or not found", (long) gca); | 1938 | printmax_t print_gca = gca; |
| 1939 | error ("GnuTLS AEAD cipher %"pMd" is invalid or not found", print_gca); | ||
| 1959 | #endif | 1940 | #endif |
| 1960 | } | 1941 | } |
| 1961 | 1942 | ||
| @@ -1980,9 +1961,7 @@ gnutls_symmetric (bool encrypting, Lisp_Object cipher, | |||
| 1980 | CHECK_CONS (iv); | 1961 | CHECK_CONS (iv); |
| 1981 | 1962 | ||
| 1982 | 1963 | ||
| 1983 | const char* desc = (encrypting ? "encrypt" : "decrypt"); | 1964 | const char *desc = encrypting ? "encrypt" : "decrypt"; |
| 1984 | |||
| 1985 | int ret = GNUTLS_E_SUCCESS; | ||
| 1986 | 1965 | ||
| 1987 | gnutls_cipher_algorithm_t gca = GNUTLS_CIPHER_UNKNOWN; | 1966 | gnutls_cipher_algorithm_t gca = GNUTLS_CIPHER_UNKNOWN; |
| 1988 | 1967 | ||
| @@ -1992,7 +1971,7 @@ gnutls_symmetric (bool encrypting, Lisp_Object cipher, | |||
| 1992 | 1971 | ||
| 1993 | if (SYMBOLP (cipher)) | 1972 | if (SYMBOLP (cipher)) |
| 1994 | info = XCDR (Fassq (cipher, Fgnutls_ciphers ())); | 1973 | info = XCDR (Fassq (cipher, Fgnutls_ciphers ())); |
| 1995 | else if (INTEGERP (cipher)) | 1974 | else if (TYPE_RANGED_INTEGERP (gnutls_cipher_algorithm_t, cipher)) |
| 1996 | gca = XINT (cipher); | 1975 | gca = XINT (cipher); |
| 1997 | else | 1976 | else |
| 1998 | info = cipher; | 1977 | info = cipher; |
| @@ -2000,41 +1979,44 @@ gnutls_symmetric (bool encrypting, Lisp_Object cipher, | |||
| 2000 | if (!NILP (info) && CONSP (info)) | 1979 | if (!NILP (info) && CONSP (info)) |
| 2001 | { | 1980 | { |
| 2002 | Lisp_Object v = Fplist_get (info, QCcipher_id); | 1981 | Lisp_Object v = Fplist_get (info, QCcipher_id); |
| 2003 | if (INTEGERP (v)) | 1982 | if (TYPE_RANGED_INTEGERP (gnutls_cipher_algorithm_t, v)) |
| 2004 | gca = XINT (v); | 1983 | gca = XINT (v); |
| 2005 | } | 1984 | } |
| 2006 | 1985 | ||
| 2007 | if (gca == GNUTLS_CIPHER_UNKNOWN) | 1986 | ptrdiff_t key_size = gnutls_cipher_get_key_size (gca); |
| 2008 | error ("GnuTLS cipher was invalid or not found"); | 1987 | if (key_size == 0) |
| 1988 | error ("GnuTLS cipher is invalid or not found"); | ||
| 2009 | 1989 | ||
| 2010 | ptrdiff_t kstart_byte, kend_byte; | 1990 | ptrdiff_t kstart_byte, kend_byte; |
| 2011 | const char* kdata = extract_data_from_object (key, &kstart_byte, &kend_byte); | 1991 | const char *kdata = extract_data_from_object (key, &kstart_byte, &kend_byte); |
| 2012 | 1992 | ||
| 2013 | if (kdata == NULL) | 1993 | if (kdata == NULL) |
| 2014 | error ("GnuTLS cipher key extraction failed"); | 1994 | error ("GnuTLS cipher key extraction failed"); |
| 2015 | 1995 | ||
| 2016 | if ((kend_byte - kstart_byte) != gnutls_cipher_get_key_size (gca)) | 1996 | if (kend_byte - kstart_byte != key_size) |
| 2017 | error ("GnuTLS cipher %s/%s key length %" pD "d was not equal to " | 1997 | error (("GnuTLS cipher %s/%s key length %"pD"d is not equal to " |
| 2018 | "the required %ld", | 1998 | "the required %"pD"d"), |
| 2019 | gnutls_cipher_get_name (gca), desc, | 1999 | gnutls_cipher_get_name (gca), desc, |
| 2020 | kend_byte - kstart_byte, (long) gnutls_cipher_get_key_size (gca)); | 2000 | kend_byte - kstart_byte, key_size); |
| 2021 | 2001 | ||
| 2022 | ptrdiff_t vstart_byte, vend_byte; | 2002 | ptrdiff_t vstart_byte, vend_byte; |
| 2023 | const char* vdata = extract_data_from_object (iv, &vstart_byte, &vend_byte); | 2003 | char *vdata = extract_data_from_object (iv, &vstart_byte, &vend_byte); |
| 2024 | 2004 | ||
| 2025 | if (vdata == NULL) | 2005 | if (vdata == NULL) |
| 2026 | error ("GnuTLS cipher IV extraction failed"); | 2006 | error ("GnuTLS cipher IV extraction failed"); |
| 2027 | 2007 | ||
| 2028 | if ((vend_byte - vstart_byte) != gnutls_cipher_get_iv_size (gca)) | 2008 | ptrdiff_t iv_size = gnutls_cipher_get_iv_size (gca); |
| 2029 | error ("GnuTLS cipher %s/%s IV length %" pD "d was not equal to " | 2009 | if (vend_byte - vstart_byte != iv_size) |
| 2030 | "the required %ld", | 2010 | error (("GnuTLS cipher %s/%s IV length %"pD"d is not equal to " |
| 2011 | "the required %"pD"d"), | ||
| 2031 | gnutls_cipher_get_name (gca), desc, | 2012 | gnutls_cipher_get_name (gca), desc, |
| 2032 | vend_byte - vstart_byte, (long) gnutls_cipher_get_iv_size (gca)); | 2013 | vend_byte - vstart_byte, iv_size); |
| 2033 | 2014 | ||
| 2034 | Lisp_Object actual_iv = make_unibyte_string (vdata, vend_byte - vstart_byte); | 2015 | Lisp_Object actual_iv = make_unibyte_string (vdata, vend_byte - vstart_byte); |
| 2035 | 2016 | ||
| 2036 | ptrdiff_t istart_byte, iend_byte; | 2017 | ptrdiff_t istart_byte, iend_byte; |
| 2037 | const char* idata = extract_data_from_object (input, &istart_byte, &iend_byte); | 2018 | const char *idata |
| 2019 | = extract_data_from_object (input, &istart_byte, &iend_byte); | ||
| 2038 | 2020 | ||
| 2039 | if (idata == NULL) | 2021 | if (idata == NULL) |
| 2040 | error ("GnuTLS cipher input extraction failed"); | 2022 | error ("GnuTLS cipher input extraction failed"); |
| @@ -2053,44 +2035,34 @@ gnutls_symmetric (bool encrypting, Lisp_Object cipher, | |||
| 2053 | return aead_output; | 2035 | return aead_output; |
| 2054 | } | 2036 | } |
| 2055 | 2037 | ||
| 2056 | if ((iend_byte - istart_byte) % gnutls_cipher_get_block_size (gca) != 0) | 2038 | ptrdiff_t cipher_block_size = gnutls_cipher_get_block_size (gca); |
| 2057 | error ("GnuTLS cipher %s/%s input block length %" pD "d was not a multiple " | 2039 | if ((iend_byte - istart_byte) % cipher_block_size != 0) |
| 2058 | "of the required %ld", | 2040 | error (("GnuTLS cipher %s/%s input block length %"pD"d is not a multiple " |
| 2041 | "of the required %"pD"d"), | ||
| 2059 | gnutls_cipher_get_name (gca), desc, | 2042 | gnutls_cipher_get_name (gca), desc, |
| 2060 | iend_byte - istart_byte, (long) gnutls_cipher_get_block_size (gca)); | 2043 | iend_byte - istart_byte, cipher_block_size); |
| 2061 | 2044 | ||
| 2062 | gnutls_cipher_hd_t hcipher; | 2045 | gnutls_cipher_hd_t hcipher; |
| 2063 | gnutls_datum_t key_datum = { (unsigned char*) kdata, kend_byte - kstart_byte }; | 2046 | gnutls_datum_t key_datum |
| 2047 | = { (unsigned char *) kdata, kend_byte - kstart_byte }; | ||
| 2064 | 2048 | ||
| 2065 | ret = gnutls_cipher_init (&hcipher, gca, &key_datum, NULL); | 2049 | int ret = gnutls_cipher_init (&hcipher, gca, &key_datum, NULL); |
| 2066 | 2050 | ||
| 2067 | if (ret < GNUTLS_E_SUCCESS) | 2051 | if (ret < GNUTLS_E_SUCCESS) |
| 2068 | { | 2052 | error ("GnuTLS cipher %s/%s initialization failed: %s", |
| 2069 | const char* str = gnutls_strerror (ret); | 2053 | gnutls_cipher_get_name (gca), desc, emacs_gnutls_strerror (ret)); |
| 2070 | if (!str) | ||
| 2071 | str = "unknown"; | ||
| 2072 | error ("GnuTLS cipher %s/%s initialization failed: %s", | ||
| 2073 | gnutls_cipher_get_name (gca), desc, str); | ||
| 2074 | } | ||
| 2075 | 2054 | ||
| 2076 | /* Note that this will not support streaming block mode. */ | 2055 | /* Note that this will not support streaming block mode. */ |
| 2077 | gnutls_cipher_set_iv (hcipher, (void*) vdata, vend_byte - vstart_byte); | 2056 | gnutls_cipher_set_iv (hcipher, vdata, vend_byte - vstart_byte); |
| 2078 | 2057 | ||
| 2079 | /* | 2058 | /* GnuTLS docs: "For the supported ciphers the encrypted data length |
| 2080 | * GnuTLS docs: "For the supported ciphers the encrypted data length | 2059 | will equal the plaintext size." */ |
| 2081 | * will equal the plaintext size." | 2060 | ptrdiff_t storage_length = iend_byte - istart_byte; |
| 2082 | */ | ||
| 2083 | size_t storage_length = iend_byte - istart_byte; | ||
| 2084 | Lisp_Object storage = make_uninit_string (storage_length); | 2061 | Lisp_Object storage = make_uninit_string (storage_length); |
| 2085 | 2062 | ||
| 2086 | if (encrypting) | 2063 | ret = ((encrypting ? gnutls_cipher_encrypt2 : gnutls_cipher_decrypt2) |
| 2087 | ret = gnutls_cipher_encrypt2 (hcipher, | 2064 | (hcipher, idata, iend_byte - istart_byte, |
| 2088 | idata, iend_byte - istart_byte, | 2065 | SSDATA (storage), storage_length)); |
| 2089 | SSDATA (storage), storage_length); | ||
| 2090 | else | ||
| 2091 | ret = gnutls_cipher_decrypt2 (hcipher, | ||
| 2092 | idata, iend_byte - istart_byte, | ||
| 2093 | SSDATA (storage), storage_length); | ||
| 2094 | 2066 | ||
| 2095 | if (STRINGP (XCAR (key))) | 2067 | if (STRINGP (XCAR (key))) |
| 2096 | Fclear_string (XCAR (key)); | 2068 | Fclear_string (XCAR (key)); |
| @@ -2098,11 +2070,8 @@ gnutls_symmetric (bool encrypting, Lisp_Object cipher, | |||
| 2098 | if (ret < GNUTLS_E_SUCCESS) | 2070 | if (ret < GNUTLS_E_SUCCESS) |
| 2099 | { | 2071 | { |
| 2100 | gnutls_cipher_deinit (hcipher); | 2072 | gnutls_cipher_deinit (hcipher); |
| 2101 | const char* str = gnutls_strerror (ret); | ||
| 2102 | if (!str) | ||
| 2103 | str = "unknown"; | ||
| 2104 | error ("GnuTLS cipher %s %sion failed: %s", | 2073 | error ("GnuTLS cipher %s %sion failed: %s", |
| 2105 | gnutls_cipher_get_name (gca), desc, str); | 2074 | gnutls_cipher_get_name (gca), desc, emacs_gnutls_strerror (ret)); |
| 2106 | } | 2075 | } |
| 2107 | 2076 | ||
| 2108 | gnutls_cipher_deinit (hcipher); | 2077 | gnutls_cipher_deinit (hcipher); |
| @@ -2110,41 +2079,46 @@ gnutls_symmetric (bool encrypting, Lisp_Object cipher, | |||
| 2110 | return list2 (storage, actual_iv); | 2079 | return list2 (storage, actual_iv); |
| 2111 | } | 2080 | } |
| 2112 | 2081 | ||
| 2113 | DEFUN ("gnutls-symmetric-encrypt", Fgnutls_symmetric_encrypt, Sgnutls_symmetric_encrypt, 4, 5, 0, | 2082 | DEFUN ("gnutls-symmetric-encrypt", Fgnutls_symmetric_encrypt, |
| 2083 | Sgnutls_symmetric_encrypt, 4, 5, 0, | ||
| 2114 | doc: /* Encrypt INPUT with symmetric CIPHER, KEY+AEAD_AUTH, and IV to a unibyte string. | 2084 | doc: /* Encrypt INPUT with symmetric CIPHER, KEY+AEAD_AUTH, and IV to a unibyte string. |
| 2115 | 2085 | ||
| 2116 | Returns nil on error. | 2086 | Return nil on error. |
| 2117 | 2087 | ||
| 2118 | The KEY can be specified as a buffer or string or in other ways | 2088 | The KEY can be specified as a buffer or string or in other ways (see |
| 2119 | (see Info node `(elisp)Format of GnuTLS Cryptography Inputs'). The KEY will be | 2089 | Info node `(elisp)Format of GnuTLS Cryptography Inputs'). The KEY |
| 2120 | wiped after use if it's a string. | 2090 | will be wiped after use if it's a string. |
| 2121 | 2091 | ||
| 2122 | The IV and INPUT and the optional AEAD_AUTH can be | 2092 | The IV and INPUT and the optional AEAD_AUTH can be specified as a |
| 2123 | specified as a buffer or string or in other ways (see Info node `(elisp)Format of GnuTLS Cryptography Inputs'). | 2093 | buffer or string or in other ways (see Info node `(elisp)Format of |
| 2094 | GnuTLS Cryptography Inputs'). | ||
| 2124 | 2095 | ||
| 2125 | The alist of symmetric ciphers can be obtained with `gnutls-ciphers`. | 2096 | The alist of symmetric ciphers can be obtained with `gnutls-ciphers`. |
| 2126 | The CIPHER may be a string or symbol matching a key in that alist, or | 2097 | The CIPHER may be a string or symbol matching a key in that alist, or |
| 2127 | a plist with the `:cipher-id' numeric property, or the number itself. | 2098 | a plist with the :cipher-id numeric property, or the number itself. |
| 2128 | 2099 | ||
| 2129 | AEAD ciphers: these ciphers will have a `gnutls-ciphers' entry with | 2100 | AEAD ciphers: these ciphers will have a `gnutls-ciphers' entry with |
| 2130 | :cipher-aead-capable set to t. AEAD_AUTH can be supplied for | 2101 | :cipher-aead-capable set to t. AEAD_AUTH can be supplied for |
| 2131 | these AEAD ciphers, but it may still be omitted (nil) as well. */) | 2102 | these AEAD ciphers, but it may still be omitted (nil) as well. */) |
| 2132 | (Lisp_Object cipher, Lisp_Object key, Lisp_Object iv, Lisp_Object input, Lisp_Object aead_auth) | 2103 | (Lisp_Object cipher, Lisp_Object key, Lisp_Object iv, |
| 2104 | Lisp_Object input, Lisp_Object aead_auth) | ||
| 2133 | { | 2105 | { |
| 2134 | return gnutls_symmetric (true, cipher, key, iv, input, aead_auth); | 2106 | return gnutls_symmetric (true, cipher, key, iv, input, aead_auth); |
| 2135 | } | 2107 | } |
| 2136 | 2108 | ||
| 2137 | DEFUN ("gnutls-symmetric-decrypt", Fgnutls_symmetric_decrypt, Sgnutls_symmetric_decrypt, 4, 5, 0, | 2109 | DEFUN ("gnutls-symmetric-decrypt", Fgnutls_symmetric_decrypt, |
| 2110 | Sgnutls_symmetric_decrypt, 4, 5, 0, | ||
| 2138 | doc: /* Decrypt INPUT with symmetric CIPHER, KEY+AEAD_AUTH, and IV to a unibyte string. | 2111 | doc: /* Decrypt INPUT with symmetric CIPHER, KEY+AEAD_AUTH, and IV to a unibyte string. |
| 2139 | 2112 | ||
| 2140 | Returns nil on error. | 2113 | Return nil on error. |
| 2141 | 2114 | ||
| 2142 | The KEY can be specified as a buffer or string or in other ways | 2115 | The KEY can be specified as a buffer or string or in other ways (see |
| 2143 | (see Info node `(elisp)Format of GnuTLS Cryptography Inputs'). The KEY will be | 2116 | Info node `(elisp)Format of GnuTLS Cryptography Inputs'). The KEY |
| 2144 | wiped after use if it's a string. | 2117 | will be wiped after use if it's a string. |
| 2145 | 2118 | ||
| 2146 | The IV and INPUT and the optional AEAD_AUTH can be | 2119 | The IV and INPUT and the optional AEAD_AUTH can be specified as a |
| 2147 | specified as a buffer or string or in other ways (see Info node `(elisp)Format of GnuTLS Cryptography Inputs'). | 2120 | buffer or string or in other ways (see Info node `(elisp)Format of |
| 2121 | GnuTLS Cryptography Inputs'). | ||
| 2148 | 2122 | ||
| 2149 | The alist of symmetric ciphers can be obtained with `gnutls-ciphers`. | 2123 | The alist of symmetric ciphers can be obtained with `gnutls-ciphers`. |
| 2150 | The CIPHER may be a string or symbol matching a key in that alist, or | 2124 | The CIPHER may be a string or symbol matching a key in that alist, or |
| @@ -2153,7 +2127,8 @@ a plist with the `:cipher-id' numeric property, or the number itself. | |||
| 2153 | AEAD ciphers: these ciphers will have a `gnutls-ciphers' entry with | 2127 | AEAD ciphers: these ciphers will have a `gnutls-ciphers' entry with |
| 2154 | :cipher-aead-capable set to t. AEAD_AUTH can be supplied for | 2128 | :cipher-aead-capable set to t. AEAD_AUTH can be supplied for |
| 2155 | these AEAD ciphers, but it may still be omitted (nil) as well. */) | 2129 | these AEAD ciphers, but it may still be omitted (nil) as well. */) |
| 2156 | (Lisp_Object cipher, Lisp_Object key, Lisp_Object iv, Lisp_Object input, Lisp_Object aead_auth) | 2130 | (Lisp_Object cipher, Lisp_Object key, Lisp_Object iv, |
| 2131 | Lisp_Object input, Lisp_Object aead_auth) | ||
| 2157 | { | 2132 | { |
| 2158 | return gnutls_symmetric (false, cipher, key, iv, input, aead_auth); | 2133 | return gnutls_symmetric (false, cipher, key, iv, input, aead_auth); |
| 2159 | } | 2134 | } |
| @@ -2164,32 +2139,26 @@ DEFUN ("gnutls-macs", Fgnutls_macs, Sgnutls_macs, 0, 0, 0, | |||
| 2164 | Use the value of the alist (extract it with `alist-get' for instance) | 2139 | Use the value of the alist (extract it with `alist-get' for instance) |
| 2165 | with `gnutls-hash-mac'. The alist key is the mac-algorithm method | 2140 | with `gnutls-hash-mac'. The alist key is the mac-algorithm method |
| 2166 | name. */) | 2141 | name. */) |
| 2167 | (void) | 2142 | (void) |
| 2168 | { | 2143 | { |
| 2169 | Lisp_Object mac_algorithms = Qnil; | 2144 | Lisp_Object mac_algorithms = Qnil; |
| 2170 | const gnutls_mac_algorithm_t* macs = gnutls_mac_list (); | 2145 | const gnutls_mac_algorithm_t *macs = gnutls_mac_list (); |
| 2171 | for (size_t pos = 0; macs[pos] != 0; pos++) | 2146 | for (ptrdiff_t pos = 0; macs[pos] != 0; pos++) |
| 2172 | { | 2147 | { |
| 2173 | const gnutls_mac_algorithm_t gma = macs[pos]; | 2148 | const gnutls_mac_algorithm_t gma = macs[pos]; |
| 2174 | 2149 | ||
| 2175 | const char* name = gnutls_mac_get_name (gma); | 2150 | const char *name = gnutls_mac_get_name (gma); |
| 2176 | 2151 | ||
| 2177 | Lisp_Object mp = listn (CONSTYPE_HEAP, 11, | 2152 | Lisp_Object mp = listn (CONSTYPE_HEAP, 11, intern (name), |
| 2178 | /* A symbol representing the mac-algorithm. */ | 2153 | QCmac_algorithm_id, make_number (gma), |
| 2179 | intern (name), | 2154 | QCtype, Qgnutls_type_mac_algorithm, |
| 2180 | /* The internally meaningful mac-algorithm ID. */ | 2155 | |
| 2181 | QCmac_algorithm_id, | ||
| 2182 | make_number (gma), | ||
| 2183 | /* The type (vs. other GnuTLS objects). */ | ||
| 2184 | QCtype, | ||
| 2185 | Qgnutls_type_mac_algorithm, | ||
| 2186 | /* The output length. */ | ||
| 2187 | QCmac_algorithm_length, | 2156 | QCmac_algorithm_length, |
| 2188 | make_number (gnutls_hmac_get_len (gma)), | 2157 | make_number (gnutls_hmac_get_len (gma)), |
| 2189 | /* The key size. */ | 2158 | |
| 2190 | QCmac_algorithm_keysize, | 2159 | QCmac_algorithm_keysize, |
| 2191 | make_number (gnutls_mac_get_key_size (gma)), | 2160 | make_number (gnutls_mac_get_key_size (gma)), |
| 2192 | /* The nonce size. */ | 2161 | |
| 2193 | QCmac_algorithm_noncesize, | 2162 | QCmac_algorithm_noncesize, |
| 2194 | make_number (gnutls_mac_get_nonce_size (gma))); | 2163 | make_number (gnutls_mac_get_nonce_size (gma))); |
| 2195 | mac_algorithms = Fcons (mp, mac_algorithms); | 2164 | mac_algorithms = Fcons (mp, mac_algorithms); |
| @@ -2204,25 +2173,20 @@ DEFUN ("gnutls-digests", Fgnutls_digests, Sgnutls_digests, 0, 0, 0, | |||
| 2204 | Use the value of the alist (extract it with `alist-get' for instance) | 2173 | Use the value of the alist (extract it with `alist-get' for instance) |
| 2205 | with `gnutls-hash-digest'. The alist key is the digest-algorithm | 2174 | with `gnutls-hash-digest'. The alist key is the digest-algorithm |
| 2206 | method name. */) | 2175 | method name. */) |
| 2207 | (void) | 2176 | (void) |
| 2208 | { | 2177 | { |
| 2209 | Lisp_Object digest_algorithms = Qnil; | 2178 | Lisp_Object digest_algorithms = Qnil; |
| 2210 | const gnutls_digest_algorithm_t* digests = gnutls_digest_list (); | 2179 | const gnutls_digest_algorithm_t *digests = gnutls_digest_list (); |
| 2211 | for (size_t pos = 0; digests[pos] != 0; pos++) | 2180 | for (ptrdiff_t pos = 0; digests[pos] != 0; pos++) |
| 2212 | { | 2181 | { |
| 2213 | const gnutls_digest_algorithm_t gda = digests[pos]; | 2182 | const gnutls_digest_algorithm_t gda = digests[pos]; |
| 2214 | 2183 | ||
| 2215 | const char* name = gnutls_digest_get_name (gda); | 2184 | const char *name = gnutls_digest_get_name (gda); |
| 2216 | 2185 | ||
| 2217 | Lisp_Object mp = listn (CONSTYPE_HEAP, 7, | 2186 | Lisp_Object mp = listn (CONSTYPE_HEAP, 7, intern (name), |
| 2218 | /* A symbol representing the digest-algorithm. */ | 2187 | QCdigest_algorithm_id, make_number (gda), |
| 2219 | intern (name), | 2188 | QCtype, Qgnutls_type_digest_algorithm, |
| 2220 | /* The internally meaningful digest-algorithm ID. */ | 2189 | |
| 2221 | QCdigest_algorithm_id, | ||
| 2222 | make_number (gda), | ||
| 2223 | QCtype, | ||
| 2224 | Qgnutls_type_digest_algorithm, | ||
| 2225 | /* The digest length. */ | ||
| 2226 | QCdigest_algorithm_length, | 2190 | QCdigest_algorithm_length, |
| 2227 | make_number (gnutls_hash_get_len (gda))); | 2191 | make_number (gnutls_hash_get_len (gda))); |
| 2228 | 2192 | ||
| @@ -2235,11 +2199,11 @@ method name. */) | |||
| 2235 | DEFUN ("gnutls-hash-mac", Fgnutls_hash_mac, Sgnutls_hash_mac, 3, 3, 0, | 2199 | DEFUN ("gnutls-hash-mac", Fgnutls_hash_mac, Sgnutls_hash_mac, 3, 3, 0, |
| 2236 | doc: /* Hash INPUT with HASH-METHOD and KEY into a unibyte string. | 2200 | doc: /* Hash INPUT with HASH-METHOD and KEY into a unibyte string. |
| 2237 | 2201 | ||
| 2238 | Returns nil on error. | 2202 | Return nil on error. |
| 2239 | 2203 | ||
| 2240 | The KEY can be specified as a buffer or string or in other ways | 2204 | The KEY can be specified as a buffer or string or in other ways (see |
| 2241 | (see Info node `(elisp)Format of GnuTLS Cryptography Inputs'). The KEY will be | 2205 | Info node `(elisp)Format of GnuTLS Cryptography Inputs'). The KEY |
| 2242 | wiped after use if it's a string. | 2206 | will be wiped after use if it's a string. |
| 2243 | 2207 | ||
| 2244 | The INPUT can be specified as a buffer or string or in other | 2208 | The INPUT can be specified as a buffer or string or in other |
| 2245 | ways (see Info node `(elisp)Format of GnuTLS Cryptography Inputs'). | 2209 | ways (see Info node `(elisp)Format of GnuTLS Cryptography Inputs'). |
| @@ -2248,7 +2212,7 @@ The alist of MAC algorithms can be obtained with `gnutls-macs`. The | |||
| 2248 | HASH-METHOD may be a string or symbol matching a key in that alist, or | 2212 | HASH-METHOD may be a string or symbol matching a key in that alist, or |
| 2249 | a plist with the `:mac-algorithm-id' numeric property, or the number | 2213 | a plist with the `:mac-algorithm-id' numeric property, or the number |
| 2250 | itself. */) | 2214 | itself. */) |
| 2251 | (Lisp_Object hash_method, Lisp_Object key, Lisp_Object input) | 2215 | (Lisp_Object hash_method, Lisp_Object key, Lisp_Object input) |
| 2252 | { | 2216 | { |
| 2253 | if (BUFFERP (input) || STRINGP (input)) | 2217 | if (BUFFERP (input) || STRINGP (input)) |
| 2254 | input = list1 (input); | 2218 | input = list1 (input); |
| @@ -2260,8 +2224,6 @@ itself. */) | |||
| 2260 | 2224 | ||
| 2261 | CHECK_CONS (key); | 2225 | CHECK_CONS (key); |
| 2262 | 2226 | ||
| 2263 | int ret = GNUTLS_E_SUCCESS; | ||
| 2264 | |||
| 2265 | gnutls_mac_algorithm_t gma = GNUTLS_MAC_UNKNOWN; | 2227 | gnutls_mac_algorithm_t gma = GNUTLS_MAC_UNKNOWN; |
| 2266 | 2228 | ||
| 2267 | Lisp_Object info = Qnil; | 2229 | Lisp_Object info = Qnil; |
| @@ -2270,7 +2232,7 @@ itself. */) | |||
| 2270 | 2232 | ||
| 2271 | if (SYMBOLP (hash_method)) | 2233 | if (SYMBOLP (hash_method)) |
| 2272 | info = XCDR (Fassq (hash_method, Fgnutls_macs ())); | 2234 | info = XCDR (Fassq (hash_method, Fgnutls_macs ())); |
| 2273 | else if (INTEGERP (hash_method)) | 2235 | else if (TYPE_RANGED_INTEGERP (gnutls_mac_algorithm_t, hash_method)) |
| 2274 | gma = XINT (hash_method); | 2236 | gma = XINT (hash_method); |
| 2275 | else | 2237 | else |
| 2276 | info = hash_method; | 2238 | info = hash_method; |
| @@ -2278,37 +2240,32 @@ itself. */) | |||
| 2278 | if (!NILP (info) && CONSP (info)) | 2240 | if (!NILP (info) && CONSP (info)) |
| 2279 | { | 2241 | { |
| 2280 | Lisp_Object v = Fplist_get (info, QCmac_algorithm_id); | 2242 | Lisp_Object v = Fplist_get (info, QCmac_algorithm_id); |
| 2281 | if (INTEGERP (v)) | 2243 | if (TYPE_RANGED_INTEGERP (gnutls_mac_algorithm_t, v)) |
| 2282 | gma = XINT (v); | 2244 | gma = XINT (v); |
| 2283 | } | 2245 | } |
| 2284 | 2246 | ||
| 2285 | if (gma == GNUTLS_MAC_UNKNOWN) | 2247 | ptrdiff_t digest_length = gnutls_hmac_get_len (gma); |
| 2286 | error ("GnuTLS MAC-method was invalid or not found"); | 2248 | if (digest_length == 0) |
| 2249 | error ("GnuTLS MAC-method is invalid or not found"); | ||
| 2287 | 2250 | ||
| 2288 | ptrdiff_t kstart_byte, kend_byte; | 2251 | ptrdiff_t kstart_byte, kend_byte; |
| 2289 | const char* kdata = extract_data_from_object (key, &kstart_byte, &kend_byte); | 2252 | const char *kdata = extract_data_from_object (key, &kstart_byte, &kend_byte); |
| 2290 | gnutls_hmac_hd_t hmac; | ||
| 2291 | ret = gnutls_hmac_init (&hmac, gma, | ||
| 2292 | kdata + kstart_byte, kend_byte - kstart_byte); | ||
| 2293 | |||
| 2294 | if (kdata == NULL) | 2253 | if (kdata == NULL) |
| 2295 | error ("GnuTLS MAC key extraction failed"); | 2254 | error ("GnuTLS MAC key extraction failed"); |
| 2296 | 2255 | ||
| 2256 | gnutls_hmac_hd_t hmac; | ||
| 2257 | int ret = gnutls_hmac_init (&hmac, gma, | ||
| 2258 | kdata + kstart_byte, kend_byte - kstart_byte); | ||
| 2297 | if (ret < GNUTLS_E_SUCCESS) | 2259 | if (ret < GNUTLS_E_SUCCESS) |
| 2298 | { | 2260 | error ("GnuTLS MAC %s initialization failed: %s", |
| 2299 | const char* str = gnutls_strerror (ret); | 2261 | gnutls_mac_get_name (gma), emacs_gnutls_strerror (ret)); |
| 2300 | if (!str) | ||
| 2301 | str = "unknown"; | ||
| 2302 | error ("GnuTLS MAC %s initialization failed: %s", | ||
| 2303 | gnutls_mac_get_name (gma), str); | ||
| 2304 | } | ||
| 2305 | 2262 | ||
| 2306 | ptrdiff_t istart_byte, iend_byte; | 2263 | ptrdiff_t istart_byte, iend_byte; |
| 2307 | const char* idata = extract_data_from_object (input, &istart_byte, &iend_byte); | 2264 | const char *idata |
| 2265 | = extract_data_from_object (input, &istart_byte, &iend_byte); | ||
| 2308 | if (idata == NULL) | 2266 | if (idata == NULL) |
| 2309 | error ("GnuTLS MAC input extraction failed"); | 2267 | error ("GnuTLS MAC input extraction failed"); |
| 2310 | 2268 | ||
| 2311 | size_t digest_length = gnutls_hmac_get_len (gma); | ||
| 2312 | Lisp_Object digest = make_uninit_string (digest_length); | 2269 | Lisp_Object digest = make_uninit_string (digest_length); |
| 2313 | 2270 | ||
| 2314 | ret = gnutls_hmac (hmac, idata + istart_byte, iend_byte - istart_byte); | 2271 | ret = gnutls_hmac (hmac, idata + istart_byte, iend_byte - istart_byte); |
| @@ -2319,12 +2276,8 @@ itself. */) | |||
| 2319 | if (ret < GNUTLS_E_SUCCESS) | 2276 | if (ret < GNUTLS_E_SUCCESS) |
| 2320 | { | 2277 | { |
| 2321 | gnutls_hmac_deinit (hmac, NULL); | 2278 | gnutls_hmac_deinit (hmac, NULL); |
| 2322 | |||
| 2323 | const char* str = gnutls_strerror (ret); | ||
| 2324 | if (!str) | ||
| 2325 | str = "unknown"; | ||
| 2326 | error ("GnuTLS MAC %s application failed: %s", | 2279 | error ("GnuTLS MAC %s application failed: %s", |
| 2327 | gnutls_mac_get_name (gma), str); | 2280 | gnutls_mac_get_name (gma), emacs_gnutls_strerror (ret)); |
| 2328 | } | 2281 | } |
| 2329 | 2282 | ||
| 2330 | gnutls_hmac_output (hmac, SSDATA (digest)); | 2283 | gnutls_hmac_output (hmac, SSDATA (digest)); |
| @@ -2336,7 +2289,7 @@ itself. */) | |||
| 2336 | DEFUN ("gnutls-hash-digest", Fgnutls_hash_digest, Sgnutls_hash_digest, 2, 2, 0, | 2289 | DEFUN ("gnutls-hash-digest", Fgnutls_hash_digest, Sgnutls_hash_digest, 2, 2, 0, |
| 2337 | doc: /* Digest INPUT with DIGEST-METHOD into a unibyte string. | 2290 | doc: /* Digest INPUT with DIGEST-METHOD into a unibyte string. |
| 2338 | 2291 | ||
| 2339 | Returns nil on error. | 2292 | Return nil on error. |
| 2340 | 2293 | ||
| 2341 | The INPUT can be specified as a buffer or string or in other | 2294 | The INPUT can be specified as a buffer or string or in other |
| 2342 | ways (see Info node `(elisp)Format of GnuTLS Cryptography Inputs'). | 2295 | ways (see Info node `(elisp)Format of GnuTLS Cryptography Inputs'). |
| @@ -2345,15 +2298,13 @@ The alist of digest algorithms can be obtained with `gnutls-digests`. | |||
| 2345 | The DIGEST-METHOD may be a string or symbol matching a key in that | 2298 | The DIGEST-METHOD may be a string or symbol matching a key in that |
| 2346 | alist, or a plist with the `:digest-algorithm-id' numeric property, or | 2299 | alist, or a plist with the `:digest-algorithm-id' numeric property, or |
| 2347 | the number itself. */) | 2300 | the number itself. */) |
| 2348 | (Lisp_Object digest_method, Lisp_Object input) | 2301 | (Lisp_Object digest_method, Lisp_Object input) |
| 2349 | { | 2302 | { |
| 2350 | if (BUFFERP (input) || STRINGP (input)) | 2303 | if (BUFFERP (input) || STRINGP (input)) |
| 2351 | input = list1 (input); | 2304 | input = list1 (input); |
| 2352 | 2305 | ||
| 2353 | CHECK_CONS (input); | 2306 | CHECK_CONS (input); |
| 2354 | 2307 | ||
| 2355 | int ret = GNUTLS_E_SUCCESS; | ||
| 2356 | |||
| 2357 | gnutls_digest_algorithm_t gda = GNUTLS_DIG_UNKNOWN; | 2308 | gnutls_digest_algorithm_t gda = GNUTLS_DIG_UNKNOWN; |
| 2358 | 2309 | ||
| 2359 | Lisp_Object info = Qnil; | 2310 | Lisp_Object info = Qnil; |
| @@ -2362,7 +2313,7 @@ the number itself. */) | |||
| 2362 | 2313 | ||
| 2363 | if (SYMBOLP (digest_method)) | 2314 | if (SYMBOLP (digest_method)) |
| 2364 | info = XCDR (Fassq (digest_method, Fgnutls_digests ())); | 2315 | info = XCDR (Fassq (digest_method, Fgnutls_digests ())); |
| 2365 | else if (INTEGERP (digest_method)) | 2316 | else if (TYPE_RANGED_INTEGERP (gnutls_digest_algorithm_t, digest_method)) |
| 2366 | gda = XINT (digest_method); | 2317 | gda = XINT (digest_method); |
| 2367 | else | 2318 | else |
| 2368 | info = digest_method; | 2319 | info = digest_method; |
| @@ -2370,29 +2321,26 @@ the number itself. */) | |||
| 2370 | if (!NILP (info) && CONSP (info)) | 2321 | if (!NILP (info) && CONSP (info)) |
| 2371 | { | 2322 | { |
| 2372 | Lisp_Object v = Fplist_get (info, QCdigest_algorithm_id); | 2323 | Lisp_Object v = Fplist_get (info, QCdigest_algorithm_id); |
| 2373 | if (INTEGERP (v)) | 2324 | if (TYPE_RANGED_INTEGERP (gnutls_digest_algorithm_t, v)) |
| 2374 | gda = XINT (v); | 2325 | gda = XINT (v); |
| 2375 | } | 2326 | } |
| 2376 | 2327 | ||
| 2377 | if (gda == GNUTLS_DIG_UNKNOWN) | 2328 | ptrdiff_t digest_length = gnutls_hash_get_len (gda); |
| 2378 | error ("GnuTLS digest-method was invalid or not found"); | 2329 | if (digest_length == 0) |
| 2330 | error ("GnuTLS digest-method is invalid or not found"); | ||
| 2379 | 2331 | ||
| 2380 | gnutls_hash_hd_t hash; | 2332 | gnutls_hash_hd_t hash; |
| 2381 | ret = gnutls_hash_init (&hash, gda); | 2333 | int ret = gnutls_hash_init (&hash, gda); |
| 2382 | 2334 | ||
| 2383 | if (ret < GNUTLS_E_SUCCESS) | 2335 | if (ret < GNUTLS_E_SUCCESS) |
| 2384 | { | 2336 | error ("GnuTLS digest initialization failed: %s", |
| 2385 | const char* str = gnutls_strerror (ret); | 2337 | emacs_gnutls_strerror (ret)); |
| 2386 | if (!str) | ||
| 2387 | str = "unknown"; | ||
| 2388 | error ("GnuTLS digest initialization failed: %s", str); | ||
| 2389 | } | ||
| 2390 | 2338 | ||
| 2391 | size_t digest_length = gnutls_hash_get_len (gda); | ||
| 2392 | Lisp_Object digest = make_uninit_string (digest_length); | 2339 | Lisp_Object digest = make_uninit_string (digest_length); |
| 2393 | 2340 | ||
| 2394 | ptrdiff_t istart_byte, iend_byte; | 2341 | ptrdiff_t istart_byte, iend_byte; |
| 2395 | const char* idata = extract_data_from_object (input, &istart_byte, &iend_byte); | 2342 | const char *idata |
| 2343 | = extract_data_from_object (input, &istart_byte, &iend_byte); | ||
| 2396 | if (idata == NULL) | 2344 | if (idata == NULL) |
| 2397 | error ("GnuTLS digest input extraction failed"); | 2345 | error ("GnuTLS digest input extraction failed"); |
| 2398 | 2346 | ||
| @@ -2401,11 +2349,8 @@ the number itself. */) | |||
| 2401 | if (ret < GNUTLS_E_SUCCESS) | 2349 | if (ret < GNUTLS_E_SUCCESS) |
| 2402 | { | 2350 | { |
| 2403 | gnutls_hash_deinit (hash, NULL); | 2351 | gnutls_hash_deinit (hash, NULL); |
| 2404 | 2352 | error ("GnuTLS digest application failed: %s", | |
| 2405 | const char* str = gnutls_strerror (ret); | 2353 | emacs_gnutls_strerror (ret)); |
| 2406 | if (!str) | ||
| 2407 | str = "unknown"; | ||
| 2408 | error ("GnuTLS digest application failed: %s", str); | ||
| 2409 | } | 2354 | } |
| 2410 | 2355 | ||
| 2411 | gnutls_hash_output (hash, SSDATA (digest)); | 2356 | gnutls_hash_output (hash, SSDATA (digest)); |
| @@ -2420,57 +2365,51 @@ DEFUN ("gnutls-available-p", Fgnutls_available_p, Sgnutls_available_p, 0, 0, 0, | |||
| 2420 | doc: /* Return list of capabilities if GnuTLS is available in this instance of Emacs. | 2365 | doc: /* Return list of capabilities if GnuTLS is available in this instance of Emacs. |
| 2421 | 2366 | ||
| 2422 | ...if supported : then... | 2367 | ...if supported : then... |
| 2423 | GnuTLS 3 or higher : the list will contain 'gnutls3. | 2368 | GnuTLS 3 or higher : the list will contain `gnutls3'. |
| 2424 | GnuTLS MACs : the list will contain 'macs. | 2369 | GnuTLS MACs : the list will contain `macs'. |
| 2425 | GnuTLS digests : the list will contain 'digests. | 2370 | GnuTLS digests : the list will contain `digests'. |
| 2426 | GnuTLS symmetric ciphers: the list will contain 'ciphers. | 2371 | GnuTLS symmetric ciphers: the list will contain `ciphers'. |
| 2427 | GnuTLS AEAD ciphers : the list will contain 'AEAD-ciphers. */) | 2372 | GnuTLS AEAD ciphers : the list will contain `AEAD-ciphers'. */) |
| 2428 | (void) | 2373 | (void) |
| 2429 | { | 2374 | { |
| 2430 | #ifdef HAVE_GNUTLS | 2375 | #ifdef WINDOWSNT |
| 2431 | Lisp_Object capabilities = Qnil; | 2376 | Lisp_Object found = Fassq (Qgnutls, Vlibrary_cache); |
| 2377 | if (CONSP (found)) | ||
| 2378 | return XCDR (found); /* TODO: use capabilities. */ | ||
| 2379 | else | ||
| 2380 | { | ||
| 2381 | Lisp_Object status; | ||
| 2382 | /* TODO: should the capabilities be dynamic here? */ | ||
| 2383 | status = init_gnutls_functions () ? capabilities : Qnil; | ||
| 2384 | Vlibrary_cache = Fcons (Fcons (Qgnutls, status), Vlibrary_cache); | ||
| 2385 | return status; | ||
| 2386 | } | ||
| 2387 | #else | ||
| 2432 | 2388 | ||
| 2433 | #ifdef HAVE_GNUTLS3 | 2389 | Lisp_Object capabilities = Qnil; |
| 2434 | 2390 | ||
| 2391 | # ifdef HAVE_GNUTLS3 | ||
| 2435 | capabilities = Fcons (intern("gnutls3"), capabilities); | 2392 | capabilities = Fcons (intern("gnutls3"), capabilities); |
| 2436 | 2393 | ||
| 2437 | #ifdef HAVE_GNUTLS3_DIGEST | 2394 | # ifdef HAVE_GNUTLS3_DIGEST |
| 2438 | capabilities = Fcons (intern("digests"), capabilities); | 2395 | capabilities = Fcons (intern("digests"), capabilities); |
| 2439 | #endif | 2396 | # endif |
| 2440 | 2397 | ||
| 2441 | #ifdef HAVE_GNUTLS3_CIPHER | 2398 | # ifdef HAVE_GNUTLS3_CIPHER |
| 2442 | capabilities = Fcons (intern("ciphers"), capabilities); | 2399 | capabilities = Fcons (intern("ciphers"), capabilities); |
| 2443 | 2400 | ||
| 2444 | #ifdef HAVE_GNUTLS3_AEAD | 2401 | # ifdef HAVE_GNUTLS3_AEAD |
| 2445 | capabilities = Fcons (intern("AEAD-ciphers"), capabilities); | 2402 | capabilities = Fcons (intern("AEAD-ciphers"), capabilities); |
| 2446 | #endif | 2403 | # endif |
| 2447 | 2404 | ||
| 2448 | #ifdef HAVE_GNUTLS3_HMAC | 2405 | # ifdef HAVE_GNUTLS3_HMAC |
| 2449 | capabilities = Fcons (intern("macs"), capabilities); | 2406 | capabilities = Fcons (intern("macs"), capabilities); |
| 2450 | #endif | 2407 | # endif |
| 2451 | 2408 | # endif | |
| 2452 | #endif | 2409 | # endif |
| 2453 | |||
| 2454 | #endif | ||
| 2455 | 2410 | ||
| 2456 | # ifdef WINDOWSNT | ||
| 2457 | Lisp_Object found = Fassq (Qgnutls, Vlibrary_cache); | ||
| 2458 | if (CONSP (found)) | ||
| 2459 | return XCDR (found); // TODO: use capabilities. | ||
| 2460 | else | ||
| 2461 | { | ||
| 2462 | Lisp_Object status; | ||
| 2463 | // TODO: should the capabilities be dynamic here? | ||
| 2464 | status = init_gnutls_functions () ? capabilities : Qnil; | ||
| 2465 | Vlibrary_cache = Fcons (Fcons (Qgnutls, status), Vlibrary_cache); | ||
| 2466 | return status; | ||
| 2467 | } | ||
| 2468 | # else /* !WINDOWSNT */ | ||
| 2469 | return capabilities; | 2411 | return capabilities; |
| 2470 | # endif /* !WINDOWSNT */ | 2412 | #endif |
| 2471 | #else /* !HAVE_GNUTLS */ | ||
| 2472 | return Qnil; | ||
| 2473 | #endif /* !HAVE_GNUTLS */ | ||
| 2474 | } | 2413 | } |
| 2475 | 2414 | ||
| 2476 | void | 2415 | void |
diff --git a/src/lisp.h b/src/lisp.h index a5134a9532c..9464bf8559f 100644 --- a/src/lisp.h +++ b/src/lisp.h | |||
| @@ -3386,9 +3386,7 @@ enum { NEXT_ALMOST_PRIME_LIMIT = 11 }; | |||
| 3386 | extern EMACS_INT next_almost_prime (EMACS_INT) ATTRIBUTE_CONST; | 3386 | extern EMACS_INT next_almost_prime (EMACS_INT) ATTRIBUTE_CONST; |
| 3387 | extern Lisp_Object larger_vector (Lisp_Object, ptrdiff_t, ptrdiff_t); | 3387 | extern Lisp_Object larger_vector (Lisp_Object, ptrdiff_t, ptrdiff_t); |
| 3388 | extern void sweep_weak_hash_tables (void); | 3388 | extern void sweep_weak_hash_tables (void); |
| 3389 | extern const char* extract_data_from_object (Lisp_Object spec, | 3389 | extern char *extract_data_from_object (Lisp_Object, ptrdiff_t *, ptrdiff_t *); |
| 3390 | ptrdiff_t *start_byte, | ||
| 3391 | ptrdiff_t *end_byte); | ||
| 3392 | EMACS_UINT hash_string (char const *, ptrdiff_t); | 3390 | EMACS_UINT hash_string (char const *, ptrdiff_t); |
| 3393 | EMACS_UINT sxhash (Lisp_Object, int); | 3391 | EMACS_UINT sxhash (Lisp_Object, int); |
| 3394 | Lisp_Object make_hash_table (struct hash_table_test, EMACS_INT, float, float, | 3392 | Lisp_Object make_hash_table (struct hash_table_test, EMACS_INT, float, float, |