📄 rfc1050.txt
字号:
RFC 1050 Remote Procedure Call April 1988 "unix.515@sun.com" and the other is "vms.515@sun.com". The first field is actually a naming method rather than an operating system name. It just happens that today, there is almost a one-to- one correspondence between naming methods and operating systems. If the world could agree on a naming standard, the first field could be the name of that standard, instead of an operating system name.9.3.2 DES Authentication Verifiers Unlike UNIX authentication, DES authentication does have a verifier so the server can validate the client's credential (and vice-versa). The contents of this verifier is primarily an encrypted timestamp. The server can decrypt this timestamp, and if it is close to what the real time is, then the client must have encrypted it correctly. The only way the client could encrypt it correctly is to know the "conversation key" of the RPC session. And, if the client knows the conversation key, then it must be the real client. The conversation key is a DES [5] key which the client generates and notifies the server of in its first RPC call. The conversation key is encrypted using a public key scheme in this first transaction. The particular public key scheme used in DES authentication is Diffie-Hellman [3], with 128-bit keys. The details of this encryption method are described later. The client and the server need the same notion of the current time in order for all of this to work. If network time synchronization cannot be guaranteed, then client can synchronize with the server before beginning the conversation, perhaps by consulting the Internet Time Server (TIME [4]). The way a server determines if a client timestamp is valid is somewhat complicated. For any other transaction but the first, the server just checks for two things: (1) the timestamp is greater than the one previously seen from the same client. (2) the timestamp has not expired. A timestamp is expired if the server's time is later than the sum of the client's timestamp, plus what is known as the client's "window". The "window" is a number the client passes (encrypted) to the server in its first transaction. You can think of it as a lifetime for the credential. This explains everything but the first transaction. In the firstSun Microsystems, Inc. [Page 13]RFC 1050 Remote Procedure Call April 1988 transaction, the server checks only that the timestamp has not expired. If this was all that was done though, then it would be quite easy for the client to send random data in place of the timestamp with a fairly good chance of succeeding. As an added check, the client sends an encrypted item in the first transaction known as the "window verifier" which must be equal to the window minus 1, or the server will reject the credential. The client too, must check the verifier returned from the server to be sure it is legitimate. The server sends back to the client the encrypted timestamp it received from the client, minus one second. If the client gets anything different than this, it will reject it.9.3.3 Nicknames and Clock Synchronization After the first transaction, the server's DES authentication subsystem returns in its verifier to the client an integer "nickname" which the client may use in its further transactions instead of passing its netname, encrypted DES key, and window every time. The nickname is most likely an index into a table on the server which stores for each client its netname, decrypted DES key, and window. Though they originally were synchronized, the client's and server's clocks can get out of sync again. When this happens, the client RPC subsystem most likely will get back "RPC_AUTHERROR" at which point it should resynchronize. A client may still get the "RPC_AUTHERROR" error even though it is synchronized with the server. The reason is that the server's nickname table is a limited size, and it may flush entries whenever it wants. A client should resend its original credential in this case and the server will give it a new nickname. If a server crashes, the entire nickname table gets flushed, and all clients will have to resend their original credentials.9.3.4 DES Authentication Protocol Specification (in XDR language) /* * There are two kinds of credentials: one in which the client uses * its full network name, and one in which it uses its "nickname" * (just an unsigned integer) given to it by the server. The * client must use its fullname in its first transaction with the * server, in which the server will return to the client its * nickname. The client may use its nickname in all further * transactions with the server. There is no requirement to use the * nickname, but it is wise to use it for performance reasons. */ enum authdes_namekind {Sun Microsystems, Inc. [Page 14]RFC 1050 Remote Procedure Call April 1988 ADN_FULLNAME = 0, ADN_NICKNAME = 1 }; /* * A 64-bit block of encrypted DES data */ typedef opaque des_block[8]; /* * Maximum length of a network user's name */ const MAXNETNAMELEN = 255; /* * A fullname contains the network name of the client, an encrypted * conversation key, and the window. The window is actually a * lifetime for the credential. If the time indicated in the * verifier timestamp plus the window has past, then the server * should expire the request and not grant it. To insure that * requests are not replayed, the server should insist that * timestamps are greater than the previous one seen, unless it is * the first transaction. In the first transaction, the server * checks instead that the window verifier is one less than the * window. */ struct authdes_fullname { string name<MAXNETNAMELEN>; /* name of client */ des_block key; /* PK encrypted conversation key */ unsigned int window; /* encrypted window */ }; /* * A credential is either a fullname or a nickname */ union authdes_cred switch (authdes_namekind adc_namekind) { case ADN_FULLNAME: authdes_fullname adc_fullname; case ADN_NICKNAME: unsigned int adc_nickname; }; /* * A timestamp encodes the time since midnight, January 1, 1970. */ struct timestamp { unsigned int seconds; /* seconds */ unsigned int useconds; /* and microseconds */Sun Microsystems, Inc. [Page 15]RFC 1050 Remote Procedure Call April 1988 }; /* * Verifier: client variety * The window verifier is only used in the first transaction. In * conjunction with a fullname credential, these items are packed * into the following structure before being encrypted: * * struct { * adv_timestamp; -- one DES block * adc_fullname.window; -- one half DES block * adv_winverf; -- one half DES block * } * This structure is encrypted using CBC mode encryption with an * input vector of zero. All other encryptions of timestamps use * ECB mode encryption. */ struct authdes_verf_clnt { timestamp adv_timestamp; /* encrypted timestamp */ unsigned int adv_winverf; /* encrypted window verifier */ }; /* * Verifier: server variety * The server returns (encrypted) the same timestamp the client * gave it minus one second. It also tells the client its nickname * to be used in future transactions (unencrypted). */ struct authdes_verf_svr { timestamp adv_timeverf; /* encrypted verifier */ unsigned int adv_nickname; /* new nickname for client */ };9.3.5 Diffie-Hellman Encryption In this scheme, there are two constants "PROOT" and "MODULUS". The particular values Sun has chosen for these for the DES authentication protocol are: const PROOT = 2; const MODULUS = "b520985fb31fcaf75036701e37d8b857"; /* in hex */ The way this scheme works is best explained by an example. Suppose there are two people "A" and "B" who want to send encrypted messages to each other. So, A and B both generate "secret" keys at random which they do not reveal to anyone. Let these keys be represented as SK(A) and SK(B). They also publish in a public directory their "public" keys. These keys are computed as follows:Sun Microsystems, Inc. [Page 16]RFC 1050 Remote Procedure Call April 1988 PK(A) = ( PROOT ** SK(A) ) mod MODULUS PK(B) = ( PROOT ** SK(B) ) mod MODULUS The "**" notation is used here to represent exponentiation. Now, both A and B can arrive at the "common" key between them, represented here as CK(A, B), without revealing their secret keys. A computes: CK(A, B) = ( PK(B) ** SK(A)) mod MODULUS while B computes: CK(A, B) = ( PK(A) ** SK(B)) mod MODULUS These two can be shown to be equivalent: (PK(B) ** SK(A)) mod MODULUS = (PK(A) ** SK(B)) mod MODULUS We drop the "mod MODULUS" parts and assume modulo arithmetic to simplify things: PK(B) ** SK(A) = PK(A) ** SK(B) Then, replace PK(B) by what B computed earlier and likewise for PK(A). ((PROOT ** SK(B)) ** SK(A) = (PROOT ** SK(A)) ** SK(B) which leads to: PROOT ** (SK(A) * SK(B)) = PROOT ** (SK(A) * SK(B)) This common key CK(A, B) is not used to encrypt the timestamps used in the protocol. Rather, it is used only to encrypt a conversation key which is then used to encrypt the timestamps. The reason for doing this is to use the common key as little as possible, for fear that it could be broken. Breaking the conversation key is a far less serious offense, since conversations are relatively short-lived. The conversation key is encrypted using 56-bit DES keys, yet the common key is 128 bits. To reduce the number of bits, 56 bits are selected from the common key as follows. The middle-most 8-bytes are selected from the common key, and then parity is added to the lower order bit of each byte, producing a 56-bit key with 8 bits of parity.Sun Microsystems, Inc. [Page 17]RFC 1050 Remote Procedure Call April 198810. RECORD MARKING STANDARD When RPC messages are passed on top of a byte stream protocol (like TCP/IP), it is necessary, or at least desirable, to delimit one message from another in order to detect and possibly recover from user protocol errors. This is called record marking (RM). Sun uses this RM/TCP/IP transport for passing RPC messages on TCP streams. One RPC message fits into one RM record. A record is composed of one or more record fragments. A record fragment is a four-byte header followed by 0 to (2**31)-1 bytes of fragment data. The bytes encode an unsigned binary number; as with XDR integers, the byte order is from highest to lowest. The number encodes two values -- a boolean which indicates whether the fragment is the last fragment of the record (bit value 1 implies the fragment is the last fragment) and a 31-bit unsigned binary value which is the length in bytes of the fragment's data. The boolean value is the highest-order bit of the header; the length is the 31 low-order bits. (Note that this record specification is NOT in XDR standard form!)11. THE RPC LANGUAGE Just as there was a need to describe the XDR data-types in a formal language, there is also need to describe the procedures that operate on these XDR data-types in a formal language as well. We use the RPC Language for this purpose. It is an extension to the XDR language. The following example is used to describe the essence of the language.11.1 An Example Service Described in the RPC Language Here is an example of the specification of a simple ping program: /* * Simple ping program */ program PING_PROG { /* * Latest and greatest version */ version PING_VERS_PINGBACK { void PINGPROC_NULL(void) = 0; /* * Ping the caller, return the round-trip time * (in microseconds). Returns -1 if the operation * timed out.Sun Microsystems, Inc. [Page 18]
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -