📄 draft-ietf-idn-dude-02.txt
字号:
u+305D u+306E u+30B9 u+30D4 u+30FC u+30C9 u+3067 DUDE: vsvpvd7hypuivf4q8. Security considerations Users expect each domain name in DNS to be controlled by a single authority. If a Unicode string intended for use as a domain label could map to multiple ACE labels, then an internationalized domain name could map to multiple ACE domain names, each controlled by a different authority, some of which could be spoofs that hijack service requests intended for another. Therefore DUDE is designed so that each Unicode string has a unique encoding. However, there can still be multiple Unicode representations of the "same" text, for various definitions of "same". This problem is addressed to some extent by the Unicode standard under the topic of canonicalization, and this work is leveraged for domain names by "nameprep" [NAMEPREP03].9. References [IDN] Internationalized Domain Names (IETF working group), http://www.i-d-n.net/, idn@ops.ietf.org. [IDNA] Patrik Faltstrom, Paul Hoffman, "Internationalizing Host Names In Applications (IDNA)", draft-ietf-idn-idna-01. [NAMEPREP03] Paul Hoffman, Marc Blanchet, "Preparation of Internationalized Host Names", 2001-Feb-24, draft-ietf-idn-nameprep-03. [RFC952] K. Harrenstien, M. Stahl, E. Feinler, "DOD Internet Host Table Specification", 1985-Oct, RFC 952. [RFC1034] P. Mockapetris, "Domain Names - Concepts and Facilities", 1987-Nov, RFC 1034. [RFC1123] Internet Engineering Task Force, R. Braden (editor), "Requirements for Internet Hosts -- Application and Support", 1989-Oct, RFC 1123. [RFC2119] Scott Bradner, "Key words for use in RFCs to Indicate Requirement Levels", 1997-Mar, RFC 2119. [SFS] David Mazieres et al, "Self-certifying File System", http://www.fs.net/. [UNICODE] The Unicode Consortium, "The Unicode Standard", http://www.unicode.org/unicode/standard/standard.html.A. Acknowledgements The basic encoding of integers to quartets to quintets to base-32 comes from earlier IETF work by Martin Duerst. DUDE uses a slight variation on the idea. Paul Hoffman provided helpful comments on this document. The idea of avoiding 0, 1, o, and l in base-32 strings was taken from SFS [SFS].B. Author contact information Mark Welter <mwelter@walid.com> Brian W. Spolarich <briansp@walid.com> WALID, Inc. State Technology Park 2245 S. State St. Ann Arbor, MI 48104 +1 734 822 2020 Adam M. Costello <amc@cs.berkeley.edu> University of California, Berkeley http://www.cs.berkeley.edu/~amc/C. Mixed-case annotation In order to use DUDE to represent case-insensitive Unicode strings, higher layers need to case-fold the Unicode strings prior to DUDE encoding. The encoded string can, however, use mixed-case base-32 (rather than all-lowercase or all-uppercase as recommended in section 4 "Base-32 characters") as an annotation telling how to convert the folded Unicode string into a mixed-case Unicode string for display purposes. Each Unicode code point (unless it is U+002D hyphen-minus) is represented by a sequence of base-32 characters, the last of which is always a letter (as opposed to a digit). If that letter is uppercase, it is a suggestion that the Unicode character be mapped to uppercase (if possible); if the letter is lowercase, it is a suggestion that the Unicode character be mapped to lowercase (if possible). DUDE encoders and decoders are not required to support these annotations, and higher layers need not use them. Example: In order to suggest that example O in section 7 "Example strings" be displayed as: <amuro><namie>-with-SUPER-MONKEYS one could capitalize the DUDE encoding as: x58jupu8nuy6gt99m-yssctqtptn-tMGFtFtH-tRCBFQtNKD. Differences from draft-ietf-idn-dude-01 Four changes have been made since draft-ietf-idn-dude-01 (DUDE-01): 1) DUDE-01 computed the XOR of each integer with the previous one in order to decide how many bits of each integer to encode, but now the XOR itself is encoded, so there is no need for a mask. 2) DUDE-01 made the first quintet of each sequence different from the rest, while now it is the last quintet that differs, so it's easier for the decoder to detect the end of the sequence. 3) The base-32 map has changed to avoid 0, 1, o, and l, to help humans avoid transcription errors. 4) The initial value of the previous code point has changed from 0 to 0x60, making the encodings of a few domain names shorter and none longer.E. Example implementation/******************************************//* dude.c 0.2.3 (2001-May-31-Thu) *//* Adam M. Costello <amc@cs.berkeley.edu> *//******************************************//* This is ANSI C code (C89) implementing *//* DUDE (draft-ietf-idn-dude-02). *//************************************************************//* Public interface (would normally go in its own .h file): */#include <limits.h>enum dude_status { dude_success, dude_bad_input, dude_big_output /* Output would exceed the space provided. */};enum case_sensitivity { case_sensitive, case_insensitive };#if UINT_MAX >= 0x1FFFFFtypedef unsigned int u_code_point;#elsetypedef unsigned long u_code_point;#endifenum dude_status dude_encode( unsigned int input_length, const u_code_point input[], const unsigned char uppercase_flags[], unsigned int *output_size, char output[] ); /* dude_encode() converts Unicode to DUDE (without any */ /* signature). The input must be represented as an array */ /* of Unicode code points (not code units; surrogate pairs */ /* are not allowed), and the output will be represented as */ /* null-terminated ASCII. The input_length is the number of code */ /* points in the input. The output_size is an in/out argument: */ /* the caller must pass in the maximum number of characters */ /* that may be output (including the terminating null), and on */ /* successful return it will contain the number of characters */ /* actually output (including the terminating null, so it will be */ /* one more than strlen() would return, which is why it is called */ /* output_size rather than output_length). The uppercase_flags */ /* array must hold input_length boolean values, where nonzero */ /* means the corresponding Unicode character should be forced */ /* to uppercase after being decoded, and zero means it is */ /* caseless or should be forced to lowercase. Alternatively, */ /* uppercase_flags may be a null pointer, which is equivalent */ /* to all zeros. The encoder always outputs lowercase base-32 */ /* characters except when nonzero values of uppercase_flags */ /* require otherwise. The return value may be any of the */ /* dude_status values defined above; if not dude_success, then */ /* output_size and output may contain garbage. On success, the */ /* encoder will never need to write an output_size greater than */ /* input_length*k+1 if all the input code points are less than 1 */ /* << (4*k), because of how the encoding is defined. */enum dude_status dude_decode( enum case_sensitivity case_sensitivity, char scratch_space[], const char input[], unsigned int *output_length, u_code_point output[], unsigned char uppercase_flags[] ); /* dude_decode() converts DUDE (without any signature) to */ /* Unicode. The input must be represented as null-terminated */ /* ASCII, and the output will be represented as an array of */ /* Unicode code points. The case_sensitivity argument influences */ /* the check on the well-formedness of the input string; it */ /* must be case_sensitive if case-sensitive comparisons are */ /* allowed on encoded strings, case_insensitive otherwise. */ /* The scratch_space must point to space at least as large */ /* as the input, which will get overwritten (this allows the */ /* decoder to avoid calling malloc()). The output_length is */ /* an in/out argument: the caller must pass in the maximum */ /* number of code points that may be output, and on successful */ /* return it will contain the actual number of code points */ /* output. The uppercase_flags array must have room for at */ /* least output_length values, or it may be a null pointer if */ /* the case information is not needed. A nonzero flag indicates */ /* that the corresponding Unicode character should be forced to */ /* uppercase by the caller, while zero means it is caseless or */ /* should be forced to lowercase. The return value may be any */ /* of the dude_status values defined above; if not dude_success, */ /* then output_length, output, and uppercase_flags may contain */ /* garbage. On success, the decoder will never need to write */ /* an output_length greater than the length of the input (not */ /* counting the null terminator), because of how the encoding is */ /* defined. *//**********************************************************//* Implementation (would normally go in its own .c file): */#include <string.h>/* Character utilities: *//* base32[q] is the lowercase base-32 character representing *//* the number q from the range 0 to 31. Note that we cannot *//* use string literals for ASCII characters because an ANSI C *//* compiler does not necessarily use ASCII. */static const char base32[] = { 97, 98, 99, 100, 101, 102, 103, 104, 105, 106, 107, /* a-k */ 109, 110, /* m-n */ 112, 113, 114, 115, 116, 117, 118, 119, 120, 121, 122, /* p-z */ 50, 51, 52, 53, 54, 55, 56, 57 /* 2-9 */};/* base32_decode(c) returns the value of a base-32 character, in the *//* range 0 to 31, or the constant base32_invalid if c is not a valid *//* base-32 character. */enum { base32_invalid = 32 };static unsigned int base32_decode(char c){ if (c < 50) return base32_invalid; if (c <= 57) return c - 26; if (c < 97) c += 32; if (c < 97 || c == 108 || c == 111 || c > 122) return base32_invalid; return c - 97 - (c > 108) - (c > 111);}/* unequal(case_sensitivity,s1,s2) returns 0 if the strings s1 and s2 *//* are equal, 1 otherwise. If case_sensitivity is case_insensitive, *//* then ASCII A-Z are considered equal to a-z respectively. */static int unequal( enum case_sensitivity case_sensitivity, const char s1[], const char s2[] ){ char c1, c2; if (case_sensitivity != case_insensitive) return strcmp(s1,s2) != 0; for (;;) { c1 = *s1; c2 = *s2; if (c1 >= 65 && c1 <= 90) c1 += 32; if (c2 >= 65 && c2 <= 90) c2 += 32; if (c1 != c2) return 1; if (c1 == 0) return 0; ++s1, ++s2; }}/* Encoder: */enum dude_status dude_encode( unsigned int input_length, const u_code_point input[], const unsigned char uppercase_flags[], unsigned int *output_size,
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -