diff options
| author | Leo Liu | 2011-06-21 16:55:22 +0800 |
|---|---|---|
| committer | Leo Liu | 2011-06-21 16:55:22 +0800 |
| commit | 7f3f739fa4e1351a5b8a2dcd290f79c2e3baba38 (patch) | |
| tree | e30470b57676daad3c70b40a6725707473ca2c50 | |
| parent | bd168c0651be4fd71141ba19d54389b26258e5bb (diff) | |
| download | emacs-7f3f739fa4e1351a5b8a2dcd290f79c2e3baba38.tar.gz emacs-7f3f739fa4e1351a5b8a2dcd290f79c2e3baba38.zip | |
New primitive secure-hash supporting md5, sha-1 and sha-2
| -rw-r--r-- | etc/ChangeLog | 4 | ||||
| -rw-r--r-- | etc/NEWS | 3 | ||||
| -rw-r--r-- | lisp/ChangeLog | 4 | ||||
| -rw-r--r-- | lisp/subr.el | 8 | ||||
| -rw-r--r-- | src/ChangeLog | 11 | ||||
| -rw-r--r-- | src/deps.mk | 4 | ||||
| -rw-r--r-- | src/fns.c | 139 | ||||
| -rw-r--r-- | src/makefile.w32-in | 2 |
8 files changed, 114 insertions, 61 deletions
diff --git a/etc/ChangeLog b/etc/ChangeLog index 109124af4ee..062edbe42a4 100644 --- a/etc/ChangeLog +++ b/etc/ChangeLog | |||
| @@ -1,3 +1,7 @@ | |||
| 1 | 2011-06-21 Leo Liu <sdl.web@gmail.com> | ||
| 2 | |||
| 3 | * NEWS: Mention the new primtive secure-hash. | ||
| 4 | |||
| 1 | 2011-06-14 Chong Yidong <cyd@stupidchicken.com> | 5 | 2011-06-14 Chong Yidong <cyd@stupidchicken.com> |
| 2 | 6 | ||
| 3 | * themes/dichromacy-theme.el: New theme. | 7 | * themes/dichromacy-theme.el: New theme. |
| @@ -305,7 +305,8 @@ If you need it, feedmail.el ought to provide a superset of the functionality. | |||
| 305 | 305 | ||
| 306 | ** The variable `focus-follows-mouse' now always defaults to nil. | 306 | ** The variable `focus-follows-mouse' now always defaults to nil. |
| 307 | 307 | ||
| 308 | ** Function `sha1' is now implemented in C for speed. | 308 | ** New primitive `secure-hash' that supports many secure hash algorithms |
| 309 | including md5, sha-1 and sha-2 (sha-224, sha-256, sha-384 and sha-512). | ||
| 309 | The elisp implementation sha1.el is removed. Feature sha1 is provided | 310 | The elisp implementation sha1.el is removed. Feature sha1 is provided |
| 310 | by default. | 311 | by default. |
| 311 | 312 | ||
diff --git a/lisp/ChangeLog b/lisp/ChangeLog index 0ab00336fe5..a31868f4ed1 100644 --- a/lisp/ChangeLog +++ b/lisp/ChangeLog | |||
| @@ -1,3 +1,7 @@ | |||
| 1 | 2011-06-21 Leo Liu <sdl.web@gmail.com> | ||
| 2 | |||
| 3 | * subr.el (sha1): Implement sha1 using secure-hash. | ||
| 4 | |||
| 1 | 2011-06-21 Martin Rudalics <rudalics@gmx.at> | 5 | 2011-06-21 Martin Rudalics <rudalics@gmx.at> |
| 2 | 6 | ||
| 3 | * window.el (display-buffer-alist): In default value do not | 7 | * window.el (display-buffer-alist): In default value do not |
diff --git a/lisp/subr.el b/lisp/subr.el index b328b7e17b7..4d2f3b1808c 100644 --- a/lisp/subr.el +++ b/lisp/subr.el | |||
| @@ -2600,6 +2600,14 @@ Otherwise, return nil." | |||
| 2600 | (get-char-property (1- (field-end pos)) 'field) | 2600 | (get-char-property (1- (field-end pos)) 'field) |
| 2601 | raw-field))) | 2601 | raw-field))) |
| 2602 | 2602 | ||
| 2603 | (defun sha1 (object &optional start end binary) | ||
| 2604 | "Return the SHA1 (Secure Hash Algorithm) of an OBJECT. | ||
| 2605 | OBJECT is either a string or a buffer. Optional arguments START and | ||
| 2606 | END are character positions specifying which portion of OBJECT for | ||
| 2607 | computing the hash. If BINARY is non-nil, return a string in binary | ||
| 2608 | form." | ||
| 2609 | (secure-hash 'sha1 object start end binary)) | ||
| 2610 | |||
| 2603 | 2611 | ||
| 2604 | ;;;; Support for yanking and text properties. | 2612 | ;;;; Support for yanking and text properties. |
| 2605 | 2613 | ||
diff --git a/src/ChangeLog b/src/ChangeLog index 5b087e8451d..279bd1be381 100644 --- a/src/ChangeLog +++ b/src/ChangeLog | |||
| @@ -1,3 +1,14 @@ | |||
| 1 | 2011-06-21 Leo Liu <sdl.web@gmail.com> | ||
| 2 | |||
| 3 | * deps.mk (fns.o): | ||
| 4 | * makefile.w32-in ($(BLD)/fns.$(O)): Include sha256.h and | ||
| 5 | sha512.h. | ||
| 6 | |||
| 7 | * fns.c (secure_hash): Rename from crypto_hash_function and change | ||
| 8 | the first arg to accept symbols. | ||
| 9 | (Fsecure_hash): New primtive. | ||
| 10 | (syms_of_fns): New symbols. | ||
| 11 | |||
| 1 | 2011-06-20 Deniz Dogan <deniz@dogan.se> | 12 | 2011-06-20 Deniz Dogan <deniz@dogan.se> |
| 2 | 13 | ||
| 3 | * process.c (Fset_process_buffer): Clarify return value in | 14 | * process.c (Fset_process_buffer): Clarify return value in |
diff --git a/src/deps.mk b/src/deps.mk index 6c677f0e6c6..080144ae1e5 100644 --- a/src/deps.mk +++ b/src/deps.mk | |||
| @@ -284,8 +284,8 @@ eval.o: eval.c commands.h keyboard.h blockinput.h atimer.h systime.h frame.h \ | |||
| 284 | floatfns.o: floatfns.c syssignal.h lisp.h globals.h $(config_h) | 284 | floatfns.o: floatfns.c syssignal.h lisp.h globals.h $(config_h) |
| 285 | fns.o: fns.c commands.h lisp.h $(config_h) frame.h buffer.h character.h \ | 285 | fns.o: fns.c commands.h lisp.h $(config_h) frame.h buffer.h character.h \ |
| 286 | keyboard.h keymap.h window.h $(INTERVALS_H) coding.h ../lib/md5.h \ | 286 | keyboard.h keymap.h window.h $(INTERVALS_H) coding.h ../lib/md5.h \ |
| 287 | ../lib/sha1.h blockinput.h atimer.h systime.h xterm.h ../lib/unistd.h \ | 287 | ../lib/sha1.h ../lib/sha256.h ../lib/sha512.h blockinput.h atimer.h \ |
| 288 | globals.h | 288 | systime.h xterm.h ../lib/unistd.h globals.h |
| 289 | print.o: print.c process.h frame.h window.h buffer.h keyboard.h character.h \ | 289 | print.o: print.c process.h frame.h window.h buffer.h keyboard.h character.h \ |
| 290 | lisp.h globals.h $(config_h) termchar.h $(INTERVALS_H) msdos.h termhooks.h \ | 290 | lisp.h globals.h $(config_h) termchar.h $(INTERVALS_H) msdos.h termhooks.h \ |
| 291 | blockinput.h atimer.h systime.h font.h charset.h coding.h ccl.h \ | 291 | blockinput.h atimer.h systime.h font.h charset.h coding.h ccl.h \ |
| @@ -51,6 +51,8 @@ Lisp_Object Qcursor_in_echo_area; | |||
| 51 | static Lisp_Object Qwidget_type; | 51 | static Lisp_Object Qwidget_type; |
| 52 | static Lisp_Object Qcodeset, Qdays, Qmonths, Qpaper; | 52 | static Lisp_Object Qcodeset, Qdays, Qmonths, Qpaper; |
| 53 | 53 | ||
| 54 | static Lisp_Object Qmd5, Qsha1, Qsha224, Qsha256, Qsha384, Qsha512; | ||
| 55 | |||
| 54 | static int internal_equal (Lisp_Object , Lisp_Object, int, int); | 56 | static int internal_equal (Lisp_Object , Lisp_Object, int, int); |
| 55 | 57 | ||
| 56 | #ifndef HAVE_UNISTD_H | 58 | #ifndef HAVE_UNISTD_H |
| @@ -4550,21 +4552,18 @@ including negative integers. */) | |||
| 4550 | 4552 | ||
| 4551 | 4553 | ||
| 4552 | /************************************************************************ | 4554 | /************************************************************************ |
| 4553 | MD5 and SHA1 | 4555 | MD5, SHA-1, and SHA-2 |
| 4554 | ************************************************************************/ | 4556 | ************************************************************************/ |
| 4555 | 4557 | ||
| 4556 | #include "md5.h" | 4558 | #include "md5.h" |
| 4557 | #include "sha1.h" | 4559 | #include "sha1.h" |
| 4560 | #include "sha256.h" | ||
| 4561 | #include "sha512.h" | ||
| 4558 | 4562 | ||
| 4559 | /* Convert a possibly-signed character to an unsigned character. This is | 4563 | /* ALGORITHM is a symbol: md5, sha1, sha224 and so on. */ |
| 4560 | a bit safer than casting to unsigned char, since it catches some type | ||
| 4561 | errors that the cast doesn't. */ | ||
| 4562 | static inline unsigned char to_uchar (char ch) { return ch; } | ||
| 4563 | |||
| 4564 | /* TYPE: 0 for md5, 1 for sha1. */ | ||
| 4565 | 4564 | ||
| 4566 | static Lisp_Object | 4565 | static Lisp_Object |
| 4567 | crypto_hash_function (int type, Lisp_Object object, Lisp_Object start, Lisp_Object end, Lisp_Object coding_system, Lisp_Object noerror, Lisp_Object binary) | 4566 | secure_hash (Lisp_Object algorithm, Lisp_Object object, Lisp_Object start, Lisp_Object end, Lisp_Object coding_system, Lisp_Object noerror, Lisp_Object binary) |
| 4568 | { | 4567 | { |
| 4569 | int i; | 4568 | int i; |
| 4570 | EMACS_INT size; | 4569 | EMACS_INT size; |
| @@ -4574,7 +4573,11 @@ crypto_hash_function (int type, Lisp_Object object, Lisp_Object start, Lisp_Obje | |||
| 4574 | register EMACS_INT b, e; | 4573 | register EMACS_INT b, e; |
| 4575 | register struct buffer *bp; | 4574 | register struct buffer *bp; |
| 4576 | EMACS_INT temp; | 4575 | EMACS_INT temp; |
| 4577 | Lisp_Object res=Qnil; | 4576 | int digest_size; |
| 4577 | void *(*hash_func) (const char *, size_t, void *); | ||
| 4578 | Lisp_Object digest; | ||
| 4579 | |||
| 4580 | CHECK_SYMBOL (algorithm); | ||
| 4578 | 4581 | ||
| 4579 | if (STRINGP (object)) | 4582 | if (STRINGP (object)) |
| 4580 | { | 4583 | { |
| @@ -4745,47 +4748,61 @@ crypto_hash_function (int type, Lisp_Object object, Lisp_Object start, Lisp_Obje | |||
| 4745 | object = code_convert_string (object, coding_system, Qnil, 1, 0, 0); | 4748 | object = code_convert_string (object, coding_system, Qnil, 1, 0, 0); |
| 4746 | } | 4749 | } |
| 4747 | 4750 | ||
| 4748 | switch (type) | 4751 | if (EQ (algorithm, Qmd5)) |
| 4749 | { | 4752 | { |
| 4750 | case 0: /* MD5 */ | 4753 | digest_size = MD5_DIGEST_SIZE; |
| 4751 | { | 4754 | hash_func = md5_buffer; |
| 4752 | char digest[16]; | 4755 | } |
| 4753 | md5_buffer (SSDATA (object) + start_byte, | 4756 | else if (EQ (algorithm, Qsha1)) |
| 4754 | SBYTES (object) - (size_byte - end_byte), | 4757 | { |
| 4755 | digest); | 4758 | digest_size = SHA1_DIGEST_SIZE; |
| 4759 | hash_func = sha1_buffer; | ||
| 4760 | } | ||
| 4761 | else if (EQ (algorithm, Qsha224)) | ||
| 4762 | { | ||
| 4763 | digest_size = SHA224_DIGEST_SIZE; | ||
| 4764 | hash_func = sha224_buffer; | ||
| 4765 | } | ||
| 4766 | else if (EQ (algorithm, Qsha256)) | ||
| 4767 | { | ||
| 4768 | digest_size = SHA256_DIGEST_SIZE; | ||
| 4769 | hash_func = sha256_buffer; | ||
| 4770 | } | ||
| 4771 | else if (EQ (algorithm, Qsha384)) | ||
| 4772 | { | ||
| 4773 | digest_size = SHA384_DIGEST_SIZE; | ||
| 4774 | hash_func = sha384_buffer; | ||
| 4775 | } | ||
| 4776 | else if (EQ (algorithm, Qsha512)) | ||
| 4777 | { | ||
| 4778 | digest_size = SHA512_DIGEST_SIZE; | ||
| 4779 | hash_func = sha512_buffer; | ||
| 4780 | } | ||
| 4781 | else | ||
| 4782 | error ("Invalid algorithm arg: %s", SDATA (Fsymbol_name (algorithm))); | ||
| 4756 | 4783 | ||
| 4757 | if (NILP (binary)) | 4784 | /* allocate 2 x digest_size so that it can be re-used to hold the |
| 4758 | { | 4785 | hexified value */ |
| 4759 | char value[33]; | 4786 | digest = make_uninit_string (digest_size * 2); |
| 4760 | for (i = 0; i < 16; i++) | ||
| 4761 | sprintf (&value[2 * i], "%02x", to_uchar (digest[i])); | ||
| 4762 | res = make_string (value, 32); | ||
| 4763 | } | ||
| 4764 | else | ||
| 4765 | res = make_string (digest, 16); | ||
| 4766 | break; | ||
| 4767 | } | ||
| 4768 | 4787 | ||
| 4769 | case 1: /* SHA1 */ | 4788 | hash_func (SSDATA (object) + start_byte, |
| 4770 | { | 4789 | SBYTES (object) - (size_byte - end_byte), |
| 4771 | char digest[20]; | 4790 | SSDATA (digest)); |
| 4772 | sha1_buffer (SSDATA (object) + start_byte, | ||
| 4773 | SBYTES (object) - (size_byte - end_byte), | ||
| 4774 | digest); | ||
| 4775 | if (NILP (binary)) | ||
| 4776 | { | ||
| 4777 | char value[41]; | ||
| 4778 | for (i = 0; i < 20; i++) | ||
| 4779 | sprintf (&value[2 * i], "%02x", to_uchar (digest[i])); | ||
| 4780 | res = make_string (value, 40); | ||
| 4781 | } | ||
| 4782 | else | ||
| 4783 | res = make_string (digest, 20); | ||
| 4784 | break; | ||
| 4785 | } | ||
| 4786 | } | ||
| 4787 | 4791 | ||
| 4788 | return res; | 4792 | if (NILP (binary)) |
| 4793 | { | ||
| 4794 | unsigned char *p = SDATA (digest); | ||
| 4795 | for (i = digest_size - 1; i >= 0; i--) | ||
| 4796 | { | ||
| 4797 | static char const hexdigit[16] = "0123456789abcdef"; | ||
| 4798 | int p_i = p[i]; | ||
| 4799 | p[2 * i] = hexdigit[p_i >> 4]; | ||
| 4800 | p[2 * i + 1] = hexdigit[p_i & 0xf]; | ||
| 4801 | } | ||
| 4802 | return digest; | ||
| 4803 | } | ||
| 4804 | else | ||
| 4805 | return make_unibyte_string (SDATA (digest), digest_size); | ||
| 4789 | } | 4806 | } |
| 4790 | 4807 | ||
| 4791 | DEFUN ("md5", Fmd5, Smd5, 1, 5, 0, | 4808 | DEFUN ("md5", Fmd5, Smd5, 1, 5, 0, |
| @@ -4817,25 +4834,31 @@ If NOERROR is non-nil, silently assume the `raw-text' coding if the | |||
| 4817 | guesswork fails. Normally, an error is signaled in such case. */) | 4834 | guesswork fails. Normally, an error is signaled in such case. */) |
| 4818 | (Lisp_Object object, Lisp_Object start, Lisp_Object end, Lisp_Object coding_system, Lisp_Object noerror) | 4835 | (Lisp_Object object, Lisp_Object start, Lisp_Object end, Lisp_Object coding_system, Lisp_Object noerror) |
| 4819 | { | 4836 | { |
| 4820 | return crypto_hash_function (0, object, start, end, coding_system, noerror, Qnil); | 4837 | return secure_hash (Qmd5, object, start, end, coding_system, noerror, Qnil); |
| 4821 | } | 4838 | } |
| 4822 | 4839 | ||
| 4823 | DEFUN ("sha1", Fsha1, Ssha1, 1, 4, 0, | 4840 | DEFUN ("secure-hash", Fsecure_hash, Ssecure_hash, 2, 5, 0, |
| 4824 | doc: /* Return the SHA-1 (Secure Hash Algorithm) of an OBJECT. | 4841 | doc: /* Return the secure hash of an OBJECT. |
| 4825 | 4842 | ALGORITHM is a symbol: md5, sha1, sha224, sha256, sha384 or sha512. | |
| 4826 | OBJECT is either a string or a buffer. Optional arguments START and | 4843 | OBJECT is either a string or a buffer. |
| 4827 | END are character positions specifying which portion of OBJECT for | 4844 | Optional arguments START and END are character positions specifying |
| 4828 | computing the hash. If BINARY is non-nil, return a string in binary | 4845 | which portion of OBJECT for computing the hash. If BINARY is non-nil, |
| 4829 | form. */) | 4846 | return a string in binary form. */) |
| 4830 | (Lisp_Object object, Lisp_Object start, Lisp_Object end, Lisp_Object binary) | 4847 | (Lisp_Object algorithm, Lisp_Object object, Lisp_Object start, Lisp_Object end, Lisp_Object binary) |
| 4831 | { | 4848 | { |
| 4832 | return crypto_hash_function (1, object, start, end, Qnil, Qnil, binary); | 4849 | return secure_hash (algorithm, object, start, end, Qnil, Qnil, binary); |
| 4833 | } | 4850 | } |
| 4834 | |||
| 4835 | 4851 | ||
| 4836 | void | 4852 | void |
| 4837 | syms_of_fns (void) | 4853 | syms_of_fns (void) |
| 4838 | { | 4854 | { |
| 4855 | DEFSYM (Qmd5, "md5"); | ||
| 4856 | DEFSYM (Qsha1, "sha1"); | ||
| 4857 | DEFSYM (Qsha224, "sha224"); | ||
| 4858 | DEFSYM (Qsha256, "sha256"); | ||
| 4859 | DEFSYM (Qsha384, "sha384"); | ||
| 4860 | DEFSYM (Qsha512, "sha512"); | ||
| 4861 | |||
| 4839 | /* Hash table stuff. */ | 4862 | /* Hash table stuff. */ |
| 4840 | Qhash_table_p = intern_c_string ("hash-table-p"); | 4863 | Qhash_table_p = intern_c_string ("hash-table-p"); |
| 4841 | staticpro (&Qhash_table_p); | 4864 | staticpro (&Qhash_table_p); |
| @@ -5004,7 +5027,7 @@ this variable. */); | |||
| 5004 | defsubr (&Sbase64_encode_string); | 5027 | defsubr (&Sbase64_encode_string); |
| 5005 | defsubr (&Sbase64_decode_string); | 5028 | defsubr (&Sbase64_decode_string); |
| 5006 | defsubr (&Smd5); | 5029 | defsubr (&Smd5); |
| 5007 | defsubr (&Ssha1); | 5030 | defsubr (&Ssecure_hash); |
| 5008 | defsubr (&Slocale_info); | 5031 | defsubr (&Slocale_info); |
| 5009 | } | 5032 | } |
| 5010 | 5033 | ||
diff --git a/src/makefile.w32-in b/src/makefile.w32-in index d4fafcfc047..173fc673955 100644 --- a/src/makefile.w32-in +++ b/src/makefile.w32-in | |||
| @@ -867,6 +867,8 @@ $(BLD)/fns.$(O) : \ | |||
| 867 | $(EMACS_ROOT)/nt/inc/sys/time.h \ | 867 | $(EMACS_ROOT)/nt/inc/sys/time.h \ |
| 868 | $(EMACS_ROOT)/lib/md5.h \ | 868 | $(EMACS_ROOT)/lib/md5.h \ |
| 869 | $(EMACS_ROOT)/lib/sha1.h \ | 869 | $(EMACS_ROOT)/lib/sha1.h \ |
| 870 | $(EMACS_ROOT)/lib/sha256.h \ | ||
| 871 | $(EMACS_ROOT)/lib/sha512.h \ | ||
| 870 | $(LISP_H) \ | 872 | $(LISP_H) \ |
| 871 | $(SRC)/atimer.h \ | 873 | $(SRC)/atimer.h \ |
| 872 | $(SRC)/blockinput.h \ | 874 | $(SRC)/blockinput.h \ |