7.4. Handshake Protocol
The TLS Handshake Protocol is one of the defined higher-level clients of the TLS Record Protocol. This protocol is used to negotiate the secure attributes of a session. Handshake messages are supplied to the TLS Record Layer, where they are encapsulated within one or more TLSPlaintext structures, which are processed and transmitted as specified by the current active session state. enum { hello_request(0), client_hello(1), server_hello(2), certificate(11), server_key_exchange (12), certificate_request(13), server_hello_done(14), certificate_verify(15), client_key_exchange(16), finished(20), (255) } HandshakeType; struct { HandshakeType msg_type; /* handshake type */ uint24 length; /* bytes in message */ select (HandshakeType) { case hello_request: HelloRequest; case client_hello: ClientHello;
case server_hello: ServerHello; case certificate: Certificate; case server_key_exchange: ServerKeyExchange; case certificate_request: CertificateRequest; case server_hello_done: ServerHelloDone; case certificate_verify: CertificateVerify; case client_key_exchange: ClientKeyExchange; case finished: Finished; } body; } Handshake; The handshake protocol messages are presented below in the order they MUST be sent; sending handshake messages in an unexpected order results in a fatal error. Unneeded handshake messages can be omitted, however. Note one exception to the ordering: the Certificate message is used twice in the handshake (from server to client, then from client to server), but is described only in its first position. The one message that is not bound by these ordering rules is the Hello Request message, which can be sent at any time, but which should be ignored by the client if it arrives in the middle of a handshake. New Handshake message type values MUST be defined via RFC 2434 Standards Action. See Section 11 for IANA Considerations for these values.7.4.1. Hello Messages
The hello phase messages are used to exchange security enhancement capabilities between the client and server. When a new session begins, the Record Layer's connection state encryption, hash, and compression algorithms are initialized to null. The current connection state is used for renegotiation messages.7.4.1.1. Hello request
When this message will be sent: The hello request message MAY be sent by the server at any time. Meaning of this message: Hello request is a simple notification that the client should begin the negotiation process anew by sending a client hello message when convenient. This message will be ignored by the client if the client is currently negotiating a session. This message may be ignored by the client if it does not wish to renegotiate a session, or the client may, if it wishes, respond
with a no_renegotiation alert. Since handshake messages are intended to have transmission precedence over application data, it is expected that the negotiation will begin before no more than a few records are received from the client. If the server sends a hello request but does not receive a client hello in response, it may close the connection with a fatal alert. After sending a hello request, servers SHOULD not repeat the request until the subsequent handshake negotiation is complete. Structure of this message: struct { } HelloRequest; Note: This message MUST NOT be included in the message hashes that are maintained throughout the handshake and used in the finished messages and the certificate verify message.7.4.1.2. Client Hello
When this message will be sent: When a client first connects to a server it is required to send the client hello as its first message. The client can also send a client hello in response to a hello request or on its own initiative in order to renegotiate the security parameters in an existing connection. Structure of this message: The client hello message includes a random structure, which is used later in the protocol. struct { uint32 gmt_unix_time; opaque random_bytes[28]; } Random; gmt_unix_time The current time and date in standard UNIX 32-bit format (seconds since the midnight starting Jan 1, 1970, GMT, ignoring leap seconds) according to the sender's internal clock. Clocks are not required to be set correctly by the basic TLS Protocol; higher-level or application protocols may define additional requirements. random_bytes 28 bytes generated by a secure random number generator.
The client hello message includes a variable-length session identifier. If not empty, the value identifies a session between the same client and server whose security parameters the client wishes to reuse. The session identifier MAY be from an earlier connection, from this connection, or from another currently active connection. The second option is useful if the client only wishes to update the random structures and derived values of a connection, and the third option makes it possible to establish several independent secure connections without repeating the full handshake protocol. These independent connections may occur sequentially or simultaneously; a SessionID becomes valid when the handshake negotiating it completes with the exchange of Finished messages and persists until it is removed due to aging or because a fatal error was encountered on a connection associated with the session. The actual contents of the SessionID are defined by the server. opaque SessionID<0..32>; Warning: Because the SessionID is transmitted without encryption or immediate MAC protection, servers MUST not place confidential information in session identifiers or let the contents of fake session identifiers cause any breach of security. (Note that the content of the handshake as a whole, including the SessionID, is protected by the Finished messages exchanged at the end of the handshake.) The CipherSuite list, passed from the client to the server in the client hello message, contains the combinations of cryptographic algorithms supported by the client in order of the client's preference (favorite choice first). Each CipherSuite defines a key exchange algorithm, a bulk encryption algorithm (including secret key length), and a MAC algorithm. The server will select a cipher suite or, if no acceptable choices are presented, return a handshake failure alert and close the connection. uint8 CipherSuite[2]; /* Cryptographic suite selector */ The client hello includes a list of compression algorithms supported by the client, ordered according to the client's preference.
enum { null(0), (255) } CompressionMethod; struct { ProtocolVersion client_version; Random random; SessionID session_id; CipherSuite cipher_suites<2..2^16-1>; CompressionMethod compression_methods<1..2^8-1>; } ClientHello; client_version The version of the TLS protocol by which the client wishes to communicate during this session. This SHOULD be the latest (highest valued) version supported by the client. For this version of the specification, the version will be 3.2. (See Appendix E for details about backward compatibility.) random A client-generated random structure. session_id The ID of a session the client wishes to use for this connection. This field should be empty if no session_id is available or if the client wishes to generate new security parameters. cipher_suites This is a list of the cryptographic options supported by the client, with the client's first preference first. If the session_id field is not empty (implying a session resumption request) this vector MUST include at least the cipher_suite from that session. Values are defined in Appendix A.5. compression_methods This is a list of the compression methods supported by the client, sorted by client preference. If the session_id field is not empty (implying a session resumption request) it MUST include the compression_method from that session. This vector MUST contain, and all implementations MUST support, CompressionMethod.null. Thus, a client and server will always be able to agree on a compression method. After sending the client hello message, the client waits for a server hello message. Any other handshake message returned by the server except for a hello request is treated as a fatal error. Forward compatibility note: In the interests of forward compatibility, it is permitted that a client hello message include extra data after the compression methods. This data MUST be included
in the handshake hashes, but must otherwise be ignored. This is the only handshake message for which this is legal; for all other messages, the amount of data in the message MUST match the description of the message precisely. Note: For the intended use of trailing data in the ClientHello, see RFC 3546 [TLSEXT].7.4.1.3. Server Hello
The server will send this message in response to a client hello message when it was able to find an acceptable set of algorithms. If it cannot find such a match, it will respond with a handshake failure alert. Structure of this message: struct { ProtocolVersion server_version; Random random; SessionID session_id; CipherSuite cipher_suite; CompressionMethod compression_method; } ServerHello; server_version This field will contain the lower of that suggested by the client in the client hello and the highest supported by the server. For this version of the specification, the version is 3.2. (See Appendix E for details about backward compatibility.) random This structure is generated by the server and MUST be independently generated from the ClientHello.random.
session_id This is the identity of the session corresponding to this connection. If the ClientHello.session_id was non-empty, the server will look in its session cache for a match. If a match is found and the server is willing to establish the new connection using the specified session state, the server will respond with the same value as was supplied by the client. This indicates a resumed session and dictates that the parties must proceed directly to the finished messages. Otherwise this field will contain a different value identifying the new session. The server may return an empty session_id to indicate that the session will not be cached and therefore cannot be resumed. If a session is resumed, it must be resumed using the same cipher suite it was originally negotiated with. cipher_suite The single cipher suite selected by the server from the list in ClientHello.cipher_suites. For resumed sessions, this field is the value from the state of the session being resumed. compression_method The single compression algorithm selected by the server from the list in ClientHello.compression_methods. For resumed sessions this field is the value from the resumed session state.7.4.2. Server Certificate
When this message will be sent: The server MUST send a certificate whenever the agreed-upon key exchange method is not an anonymous one. This message will always immediately follow the server hello message. Meaning of this message: The certificate type MUST be appropriate for the selected cipher suite's key exchange algorithm, and is generally an X.509v3 certificate. It MUST contain a key that matches the key exchange method, as follows. Unless otherwise specified, the signing algorithm for the certificate MUST be the same as the algorithm for the certificate key. Unless otherwise specified, the public key MAY be of any length.
Key Exchange Algorithm Certificate Key Type RSA RSA public key; the certificate MUST allow the key to be used for encryption. DHE_DSS DSS public key. DHE_RSA RSA public key that can be used for signing. DH_DSS Diffie-Hellman key. The algorithm used to sign the certificate MUST be DSS. DH_RSA Diffie-Hellman key. The algorithm used to sign the certificate MUST be RSA. All certificate profiles and key and cryptographic formats are defined by the IETF PKIX working group [PKIX]. When a key usage extension is present, the digitalSignature bit MUST be set for the key to be eligible for signing, as described above, and the keyEncipherment bit MUST be present to allow encryption, as described above. The keyAgreement bit must be set on Diffie-Hellman certificates. As CipherSuites that specify new key exchange methods are specified for the TLS Protocol, they will imply certificate format and the required encoded keying information. Structure of this message: opaque ASN.1Cert<1..2^24-1>; struct { ASN.1Cert certificate_list<0..2^24-1>; } Certificate; certificate_list This is a sequence (chain) of X.509v3 certificates. The sender's certificate must come first in the list. Each following certificate must directly certify the one preceding it. Because certificate validation requires that root keys be distributed independently, the self-signed certificate that specifies the root certificate authority may optionally be omitted from the chain, under the assumption that the remote end must already possess it in order to validate it in any case. The same message type and structure will be used for the client's response to a certificate request message. Note that a client MAY
send no certificates if it does not have an appropriate certificate to send in response to the server's authentication request. Note: PKCS #7 [PKCS7] is not used as the format for the certificate vector because PKCS #6 [PKCS6] extended certificates are not used. Also, PKCS #7 defines a SET rather than a SEQUENCE, making the task of parsing the list more difficult.7.4.3. Server Key Exchange Message
When this message will be sent: This message will be sent immediately after the server certificate message (or the server hello message, if this is an anonymous negotiation). The server key exchange message is sent by the server only when the server certificate message (if sent) does not contain enough data to allow the client to exchange a premaster secret. This is true for the following key exchange methods: DHE_DSS DHE_RSA DH_anon It is not legal to send the server key exchange message for the following key exchange methods: RSA DH_DSS DH_RSA Meaning of this message: This message conveys cryptographic information to allow the client to communicate the premaster secret: either an RSA public key with which to encrypt the premaster secret, or a Diffie-Hellman public key with which the client can complete a key exchange (with the result being the premaster secret). As additional CipherSuites are defined for TLS that include new key exchange algorithms, the server key exchange message will be sent if and only if the certificate type associated with the key exchange algorithm does not provide enough information for the client to exchange a premaster secret.
Structure of this message: enum { rsa, diffie_hellman } KeyExchangeAlgorithm; struct { opaque rsa_modulus<1..2^16-1>; opaque rsa_exponent<1..2^16-1>; } ServerRSAParams; rsa_modulus The modulus of the server's temporary RSA key. rsa_exponent The public exponent of the server's temporary RSA key. struct { opaque dh_p<1..2^16-1>; opaque dh_g<1..2^16-1>; opaque dh_Ys<1..2^16-1>; } ServerDHParams; /* Ephemeral DH parameters */ dh_p The prime modulus used for the Diffie-Hellman operation. dh_g The generator used for the Diffie-Hellman operation. dh_Ys The server's Diffie-Hellman public value (g^X mod p). struct { select (KeyExchangeAlgorithm) { case diffie_hellman: ServerDHParams params; Signature signed_params; case rsa: ServerRSAParams params; Signature signed_params; }; } ServerKeyExchange;
struct { select (KeyExchangeAlgorithm) { case diffie_hellman: ServerDHParams params; case rsa: ServerRSAParams params; }; } ServerParams; params The server's key exchange parameters. signed_params For non-anonymous key exchanges, a hash of the corresponding params value, with the signature appropriate to that hash applied. md5_hash MD5(ClientHello.random + ServerHello.random + ServerParams); sha_hash SHA(ClientHello.random + ServerHello.random + ServerParams); enum { anonymous, rsa, dsa } SignatureAlgorithm; struct { select (SignatureAlgorithm) { case anonymous: struct { }; case rsa: digitally-signed struct { opaque md5_hash[16]; opaque sha_hash[20]; }; case dsa: digitally-signed struct { opaque sha_hash[20]; }; }; }; } Signature;7.4.4. Certificate request
When this message will be sent: A non-anonymous server can optionally request a certificate from the client, if it is appropriate for the selected cipher suite.
This message, if sent, will immediately follow the Server Key Exchange message (if it is sent; otherwise, the Server Certificate message). Structure of this message: enum { rsa_sign(1), dss_sign(2), rsa_fixed_dh(3), dss_fixed_dh(4), rsa_ephemeral_dh_RESERVED(5), dss_ephemeral_dh_RESERVED(6), fortezza_dms_RESERVED(20), (255) } ClientCertificateType; opaque DistinguishedName<1..2^16-1>; struct { ClientCertificateType certificate_types<1..2^8-1>; DistinguishedName certificate_authorities<0..2^16-1>; } CertificateRequest; certificate_types This field is a list of the types of certificates requested, sorted in order of the server's preference. certificate_authorities A list of the distinguished names of acceptable certificate authorities. These distinguished names may specify a desired distinguished name for a root CA or for a subordinate CA; thus, this message can be used to describe both known roots and a desired authorization space. If the certificate_authorities list is empty then the client MAY send any certificate of the appropriate ClientCertificateType, unless there is some external arrangement to the contrary. ClientCertificateType values are divided into three groups: 1. Values from 0 (zero) through 63 decimal (0x3F) inclusive are reserved for IETF Standards Track protocols. 2. Values from 64 decimal (0x40) through 223 decimal (0xDF) inclusive are reserved for assignment for non-Standards Track methods. 3. Values from 224 decimal (0xE0) through 255 decimal (0xFF) inclusive are reserved for private use.
Additional information describing the role of IANA in the allocation of ClientCertificateType code points is described in Section 11. Note: Values listed as RESERVED may not be used. They were used in SSLv3. Note: DistinguishedName is derived from [X501]. DistinguishedNames are represented in DER-encoded format. Note: It is a fatal handshake_failure alert for an anonymous server to request client authentication.7.4.5. Server Hello Done
When this message will be sent: The server hello done message is sent by the server to indicate the end of the server hello and associated messages. After sending this message, the server will wait for a client response. Meaning of this message: This message means that the server is done sending messages to support the key exchange, and the client can proceed with its phase of the key exchange. Upon receipt of the server hello done message, the client SHOULD verify that the server provided a valid certificate, if required and check that the server hello parameters are acceptable. Structure of this message: struct { } ServerHelloDone;7.4.6. Client certificate
When this message will be sent: This is the first message the client can send after receiving a server hello done message. This message is only sent if the server requests a certificate. If no suitable certificate is available, the client SHOULD send a certificate message containing no certificates. That is, the certificate_list structure has a length of zero. If client authentication is required by the server for the handshake to continue, it may respond with a fatal handshake failure alert. Client certificates are sent using the Certificate structure defined in Section 7.4.2.
Note: When using a static Diffie-Hellman based key exchange method (DH_DSS or DH_RSA), if client authentication is requested, the Diffie-Hellman group and generator encoded in the client's certificate MUST match the server specified Diffie-Hellman parameters if the client's parameters are to be used for the key exchange.7.4.7. Client Key Exchange Message
When this message will be sent: This message is always sent by the client. It MUST immediately follow the client certificate message, if it is sent. Otherwise it MUST be the first message sent by the client after it receives the server hello done message. Meaning of this message: With this message, the premaster secret is set, either though direct transmission of the RSA-encrypted secret or by the transmission of Diffie-Hellman parameters that will allow each side to agree upon the same premaster secret. When the key exchange method is DH_RSA or DH_DSS, client certification has been requested, and the client was able to respond with a certificate that contained a Diffie-Hellman public key whose parameters (group and generator) matched those specified by the server in its certificate, this message MUST not contain any data. Structure of this message: The choice of messages depends on which key exchange method has been selected. See Section 7.4.3 for the KeyExchangeAlgorithm definition. struct { select (KeyExchangeAlgorithm) { case rsa: EncryptedPreMasterSecret; case diffie_hellman: ClientDiffieHellmanPublic; } exchange_keys; } ClientKeyExchange;7.4.7.1. RSA Encrypted Premaster Secret Message
Meaning of this message: If RSA is being used for key agreement and authentication, the client generates a 48-byte premaster secret, encrypts it using the public key from the server's certificate or the temporary RSA key
provided in a server key exchange message, and sends the result in an encrypted premaster secret message. This structure is a variant of the client key exchange message and is not a message in itself. Structure of this message: struct { ProtocolVersion client_version; opaque random[46]; } PreMasterSecret; client_version The latest (newest) version supported by the client. This is used to detect version roll-back attacks. Upon receiving the premaster secret, the server SHOULD check that this value matches the value transmitted by the client in the client hello message. random 46 securely-generated random bytes. struct { public-key-encrypted PreMasterSecret pre_master_secret; } EncryptedPreMasterSecret; pre_master_secret This random value is generated by the client and is used to generate the master secret, as specified in Section 8.1. Note: An attack discovered by Daniel Bleichenbacher [BLEI] can be used to attack a TLS server that is using PKCS#1 v 1.5 encoded RSA. The attack takes advantage of the fact that, by failing in different ways, a TLS server can be coerced into revealing whether a particular message, when decrypted, is properly PKCS#1 v1.5 formatted or not. The best way to avoid vulnerability to this attack is to treat incorrectly formatted messages in a manner indistinguishable from correctly formatted RSA blocks. Thus, when a server receives an incorrectly formatted RSA block, it should generate a random 48-byte value and proceed using it as the premaster secret. Thus, the server will act identically whether the received RSA block is correctly encoded or not. [PKCS1B] defines a newer version of PKCS#1 encoding that is more secure against the Bleichenbacher attack. However, for maximal compatibility with TLS 1.0, TLS 1.1 retains the original encoding. No variants of the Bleichenbacher attack
are known to exist provided that the above recommendations are followed. Implementation Note: Public-key-encrypted data is represented as an opaque vector <0..2^16-1> (see Section 4.7). Thus, the RSA-encrypted PreMasterSecret in a ClientKeyExchange is preceded by two length bytes. These bytes are redundant in the case of RSA because the EncryptedPreMasterSecret is the only data in the ClientKeyExchange and its length can therefore be unambiguously determined. The SSLv3 specification was not clear about the encoding of public-key-encrypted data, and therefore many SSLv3 implementations do not include the length bytes, encoding the RSA encrypted data directly in the ClientKeyExchange message. This specification requires correct encoding of the EncryptedPreMasterSecret complete with length bytes. The resulting PDU is incompatible with many SSLv3 implementations. Implementors upgrading from SSLv3 must modify their implementations to generate and accept the correct encoding. Implementors who wish to be compatible with both SSLv3 and TLS should make their implementation's behavior dependent on the protocol version. Implementation Note: It is now known that remote timing-based attacks on SSL are possible, at least when the client and server are on the same LAN. Accordingly, implementations that use static RSA keys SHOULD use RSA blinding or some other anti-timing technique, as described in [TIMING]. Note: The version number in the PreMasterSecret MUST be the version offered by the client in the ClientHello, not the version negotiated for the connection. This feature is designed to prevent rollback attacks. Unfortunately, many implementations use the negotiated version instead, and therefore checking the version number may lead to failure to interoperate with such incorrect client implementations. Client implementations, MUST and Server implementations MAY, check the version number. In practice, since the TLS handshake MACs prevent downgrade and no good attacks are known on those MACs, ambiguity is not considered a serious security risk. Note that if servers choose to check the version number, they should randomize the
PreMasterSecret in case of error, rather than generate an alert, in order to avoid variants on the Bleichenbacher attack. [KPR03]7.4.7.2. Client Diffie-Hellman Public Value
Meaning of this message: This structure conveys the client's Diffie-Hellman public value (Yc) if it was not already included in the client's certificate. The encoding used for Yc is determined by the enumerated PublicValueEncoding. This structure is a variant of the client key exchange message and not a message in itself. Structure of this message: enum { implicit, explicit } PublicValueEncoding; implicit If the client certificate already contains a suitable Diffie- Hellman key, then Yc is implicit and does not need to be sent again. In this case, the client key exchange message will be sent, but it MUST be empty. explicit Yc needs to be sent. struct { select (PublicValueEncoding) { case implicit: struct { }; case explicit: opaque dh_Yc<1..2^16-1>; } dh_public; } ClientDiffieHellmanPublic; dh_Yc The client's Diffie-Hellman public value (Yc).7.4.8. Certificate verify
When this message will be sent: This message is used to provide explicit verification of a client certificate. This message is only sent following a client certificate that has signing capability (i.e., all certificates except those containing fixed Diffie-Hellman parameters). When sent, it MUST immediately follow the client key exchange message.
Structure of this message: struct { Signature signature; } CertificateVerify; The Signature type is defined in 7.4.3. CertificateVerify.signature.md5_hash MD5(handshake_messages); CertificateVerify.signature.sha_hash SHA(handshake_messages); Here handshake_messages refers to all handshake messages sent or received starting at client hello up to but not including this message, including the type and length fields of the handshake messages. This is the concatenation of all the Handshake structures, as defined in 7.4, exchanged thus far.7.4.9. Finished
When this message will be sent: A finished message is always sent immediately after a change cipher spec message to verify that the key exchange and authentication processes were successful. It is essential that a change cipher spec message be received between the other handshake messages and the Finished message. Meaning of this message: The finished message is the first protected with the just- negotiated algorithms, keys, and secrets. Recipients of finished messages MUST verify that the contents are correct. Once a side has sent its Finished message and received and validated the Finished message from its peer, it may begin to send and receive application data over the connection. struct { opaque verify_data[12]; } Finished; verify_data PRF(master_secret, finished_label, MD5(handshake_messages) + SHA-1(handshake_messages)) [0..11];
finished_label For Finished messages sent by the client, the string "client finished". For Finished messages sent by the server, the string "server finished". handshake_messages All of the data from all messages in this handshake (not including any HelloRequest messages) up to but not including this message. This is only data visible at the handshake layer and does not include record layer headers. This is the concatenation of all the Handshake structures, as defined in 7.4, exchanged thus far. It is a fatal error if a finished message is not preceded by a change cipher spec message at the appropriate point in the handshake. The value handshake_messages includes all handshake messages starting at client hello up to, but not including, this finished message. This may be different from handshake_messages in Section 7.4.8 because it would include the certificate verify message (if sent). Also, the handshake_messages for the finished message sent by the client will be different from that for the finished message sent by the server, because the one that is sent second will include the prior one. Note: Change cipher spec messages, alerts, and any other record types are not handshake messages and are not included in the hash computations. Also, Hello Request messages are omitted from handshake hashes.8. Cryptographic Computations
In order to begin connection protection, the TLS Record Protocol requires specification of a suite of algorithms, a master secret, and the client and server random values. The authentication, encryption, and MAC algorithms are determined by the cipher_suite selected by the server and revealed in the server hello message. The compression algorithm is negotiated in the hello messages, and the random values are exchanged in the hello messages. All that remains is to calculate the master secret.8.1. Computing the Master Secret
For all key exchange methods, the same algorithm is used to convert the pre_master_secret into the master_secret. The pre_master_secret should be deleted from memory once the master_secret has been computed.
master_secret = PRF(pre_master_secret, "master secret", ClientHello.random + ServerHello.random) [0..47]; The master secret is always exactly 48 bytes in length. The length of the premaster secret will vary depending on key exchange method.8.1.1. RSA
When RSA is used for server authentication and key exchange, a 48- byte pre_master_secret is generated by the client, encrypted under the server's public key, and sent to the server. The server uses its private key to decrypt the pre_master_secret. Both parties then convert the pre_master_secret into the master_secret, as specified above. RSA digital signatures are performed using PKCS #1 [PKCS1] block type 1. RSA public key encryption is performed using PKCS #1 block type 2.8.1.2. Diffie-Hellman
A conventional Diffie-Hellman computation is performed. The negotiated key (Z) is used as the pre_master_secret, and is converted into the master_secret, as specified above. Leading bytes of Z that contain all zero bits are stripped before it is used as the pre_master_secret. Note: Diffie-Hellman parameters are specified by the server and may be either ephemeral or contained within the server's certificate.9. Mandatory Cipher Suites
In the absence of an application profile standard specifying otherwise, a TLS compliant application MUST implement the cipher suite TLS_RSA_WITH_3DES_EDE_CBC_SHA.10. Application Data Protocol
Application data messages are carried by the Record Layer and are fragmented, compressed, and encrypted based on the current connection state. The messages are treated as transparent data to the record layer.11. Security Considerations
Security issues are discussed throughout this memo, especially in Appendices D, E, and F.
12. IANA Considerations
This document describes a number of new registries that have been created by IANA. We recommended that they be placed as individual registries items under a common TLS category. Section 7.4.3 describes a TLS ClientCertificateType Registry to be maintained by the IANA, defining a number of such code point identifiers. ClientCertificateType identifiers with values in the range 0-63 (decimal) inclusive are assigned via RFC 2434 Standards Action. Values from the range 64-223 (decimal) inclusive are assigned via [RFC2434] Specification Required. Identifier values from 224-255 (decimal) inclusive are reserved for RFC 2434 Private Use. The registry will initially be populated with the values in this document, Section 7.4.4. Section A.5 describes a TLS Cipher Suite Registry to be maintained by the IANA, and it defines a number of such cipher suite identifiers. Cipher suite values with the first byte in the range 0-191 (decimal) inclusive are assigned via RFC 2434 Standards Action. Values with the first byte in the range 192-254 (decimal) are assigned via RFC 2434 Specification Required. Values with the first byte 255 (decimal) are reserved for RFC 2434 Private Use. The registry will initially be populated with the values from Section A.5 of this document, [TLSAES], and from Section 3 of [TLSKRB]. Section 6 requires that all ContentType values be defined by RFC 2434 Standards Action. IANA has created a TLS ContentType registry, initially populated with values from Section 6.2.1 of this document. Future values MUST be allocated via Standards Action as described in [RFC2434]. Section 7.2.2 requires that all Alert values be defined by RFC 2434 Standards Action. IANA has created a TLS Alert registry, initially populated with values from Section 7.2 of this document and from Section 4 of [TLSEXT]. Future values MUST be allocated via Standards Action as described in [RFC2434]. Section 7.4 requires that all HandshakeType values be defined by RFC 2434 Standards Action. IANA has created a TLS HandshakeType registry, initially populated with values from Section 7.4 of this document and from Section 2.4 of [TLSEXT]. Future values MUST be allocated via Standards Action as described in [RFC2434].
Appendix A. Protocol Constant Values
This section describes protocol types and constants.A.1. Record Layer
struct { uint8 major, minor; } ProtocolVersion; ProtocolVersion version = { 3, 2 }; /* TLS v1.1 */ enum { change_cipher_spec(20), alert(21), handshake(22), application_data(23), (255) } ContentType; struct { ContentType type; ProtocolVersion version; uint16 length; opaque fragment[TLSPlaintext.length]; } TLSPlaintext; struct { ContentType type; ProtocolVersion version; uint16 length; opaque fragment[TLSCompressed.length]; } TLSCompressed; struct { ContentType type; ProtocolVersion version; uint16 length; select (CipherSpec.cipher_type) { case stream: GenericStreamCipher; case block: GenericBlockCipher; } fragment; } TLSCiphertext; stream-ciphered struct { opaque content[TLSCompressed.length]; opaque MAC[CipherSpec.hash_size]; } GenericStreamCipher; block-ciphered struct { opaque IV[CipherSpec.block_length];
opaque content[TLSCompressed.length]; opaque MAC[CipherSpec.hash_size]; uint8 padding[GenericBlockCipher.padding_length]; uint8 padding_length; } GenericBlockCipher;A.2. Change Cipher Specs Message
struct { enum { change_cipher_spec(1), (255) } type; } ChangeCipherSpec;A.3. Alert Messages
enum { warning(1), fatal(2), (255) } AlertLevel; enum { close_notify(0), unexpected_message(10), bad_record_mac(20), decryption_failed(21), record_overflow(22), decompression_failure(30), handshake_failure(40), no_certificate_RESERVED (41), bad_certificate(42), unsupported_certificate(43), certificate_revoked(44), certificate_expired(45), certificate_unknown(46), illegal_parameter(47), unknown_ca(48), access_denied(49), decode_error(50), decrypt_error(51), export_restriction_RESERVED(60), protocol_version(70), insufficient_security(71), internal_error(80), user_canceled(90), no_renegotiation(100), (255) } AlertDescription; struct { AlertLevel level; AlertDescription description; } Alert;
A.4. Handshake Protocol
enum { hello_request(0), client_hello(1), server_hello(2), certificate(11), server_key_exchange (12), certificate_request(13), server_hello_done(14), certificate_verify(15), client_key_exchange(16), finished(20), (255) } HandshakeType; struct { HandshakeType msg_type; uint24 length; select (HandshakeType) { case hello_request: HelloRequest; case client_hello: ClientHello; case server_hello: ServerHello; case certificate: Certificate; case server_key_exchange: ServerKeyExchange; case certificate_request: CertificateRequest; case server_hello_done: ServerHelloDone; case certificate_verify: CertificateVerify; case client_key_exchange: ClientKeyExchange; case finished: Finished; } body; } Handshake;A.4.1. Hello messages
struct { } HelloRequest; struct { uint32 gmt_unix_time; opaque random_bytes[28]; } Random; opaque SessionID<0..32>; uint8 CipherSuite[2]; enum { null(0), (255) } CompressionMethod; struct { ProtocolVersion client_version; Random random; SessionID session_id; CipherSuite cipher_suites<2..2^16-1>; CompressionMethod compression_methods<1..2^8-1>;
} ClientHello; struct { ProtocolVersion server_version; Random random; SessionID session_id; CipherSuite cipher_suite; CompressionMethod compression_method; } ServerHello;A.4.2. Server Authentication and Key Exchange Messages
opaque ASN.1Cert<2^24-1>; struct { ASN.1Cert certificate_list<0..2^24-1>; } Certificate; enum { rsa, diffie_hellman } KeyExchangeAlgorithm; struct { opaque rsa_modulus<1..2^16-1>; opaque rsa_exponent<1..2^16-1>; } ServerRSAParams; struct { opaque dh_p<1..2^16-1>; opaque dh_g<1..2^16-1>; opaque dh_Ys<1..2^16-1>; } ServerDHParams; struct { select (KeyExchangeAlgorithm) { case diffie_hellman: ServerDHParams params; Signature signed_params; case rsa: ServerRSAParams params; Signature signed_params; }; } ServerKeyExchange; enum { anonymous, rsa, dsa } SignatureAlgorithm; struct { select (KeyExchangeAlgorithm) { case diffie_hellman: ServerDHParams params;
case rsa: ServerRSAParams params; }; } ServerParams; struct { select (SignatureAlgorithm) { case anonymous: struct { }; case rsa: digitally-signed struct { opaque md5_hash[16]; opaque sha_hash[20]; }; case dsa: digitally-signed struct { opaque sha_hash[20]; }; }; }; } Signature; enum { rsa_sign(1), dss_sign(2), rsa_fixed_dh(3), dss_fixed_dh(4), rsa_ephemeral_dh_RESERVED(5), dss_ephemeral_dh_RESERVED(6), fortezza_dms_RESERVED(20), (255) } ClientCertificateType; opaque DistinguishedName<1..2^16-1>; struct { ClientCertificateType certificate_types<1..2^8-1>; DistinguishedName certificate_authorities<0..2^16-1>; } CertificateRequest; struct { } ServerHelloDone;A.4.3. Client Authentication and Key Exchange Messages
struct { select (KeyExchangeAlgorithm) { case rsa: EncryptedPreMasterSecret; case diffie_hellman: ClientDiffieHellmanPublic; } exchange_keys; } ClientKeyExchange;
struct { ProtocolVersion client_version; opaque random[46]; } PreMasterSecret; struct { public-key-encrypted PreMasterSecret pre_master_secret; } EncryptedPreMasterSecret; enum { implicit, explicit } PublicValueEncoding; struct { select (PublicValueEncoding) { case implicit: struct {}; case explicit: opaque DH_Yc<1..2^16-1>; } dh_public; } ClientDiffieHellmanPublic; struct { Signature signature; } CertificateVerify;A.4.4. Handshake Finalization Message
struct { opaque verify_data[12]; } Finished;A.5. The CipherSuite
The following values define the CipherSuite codes used in the client hello and server hello messages. A CipherSuite defines a cipher specification supported in TLS Version 1.1. TLS_NULL_WITH_NULL_NULL is specified and is the initial state of a TLS connection during the first handshake on that channel, but must not be negotiated, as it provides no more protection than an unsecured connection. CipherSuite TLS_NULL_WITH_NULL_NULL = { 0x00,0x00 }; The following CipherSuite definitions require that the server provide an RSA certificate that can be used for key exchange. The server may request either an RSA or a DSS signature-capable certificate in the certificate request message.
CipherSuite TLS_RSA_WITH_NULL_MD5 = { 0x00,0x01 }; CipherSuite TLS_RSA_WITH_NULL_SHA = { 0x00,0x02 }; CipherSuite TLS_RSA_WITH_RC4_128_MD5 = { 0x00,0x04 }; CipherSuite TLS_RSA_WITH_RC4_128_SHA = { 0x00,0x05 }; CipherSuite TLS_RSA_WITH_IDEA_CBC_SHA = { 0x00,0x07 }; CipherSuite TLS_RSA_WITH_DES_CBC_SHA = { 0x00,0x09 }; CipherSuite TLS_RSA_WITH_3DES_EDE_CBC_SHA = { 0x00,0x0A }; The following CipherSuite definitions are used for server- authenticated (and optionally client-authenticated) Diffie-Hellman. DH denotes cipher suites in which the server's certificate contains the Diffie-Hellman parameters signed by the certificate authority (CA). DHE denotes ephemeral Diffie-Hellman, where the Diffie-Hellman parameters are signed by a DSS or RSA certificate that has been signed by the CA. The signing algorithm used is specified after the DH or DHE parameter. The server can request an RSA or DSS signature-capable certificate from the client for client authentication or it may request a Diffie-Hellman certificate. Any Diffie-Hellman certificate provided by the client must use the parameters (group and generator) described by the server. CipherSuite TLS_DH_DSS_WITH_DES_CBC_SHA = { 0x00,0x0C }; CipherSuite TLS_DH_DSS_WITH_3DES_EDE_CBC_SHA = { 0x00,0x0D }; CipherSuite TLS_DH_RSA_WITH_DES_CBC_SHA = { 0x00,0x0F }; CipherSuite TLS_DH_RSA_WITH_3DES_EDE_CBC_SHA = { 0x00,0x10 }; CipherSuite TLS_DHE_DSS_WITH_DES_CBC_SHA = { 0x00,0x12 }; CipherSuite TLS_DHE_DSS_WITH_3DES_EDE_CBC_SHA = { 0x00,0x13 }; CipherSuite TLS_DHE_RSA_WITH_DES_CBC_SHA = { 0x00,0x15 }; CipherSuite TLS_DHE_RSA_WITH_3DES_EDE_CBC_SHA = { 0x00,0x16 }; The following cipher suites are used for completely anonymous Diffie-Hellman communications in which neither party is authenticated. Note that this mode is vulnerable to man-in-the- middle attacks and is therefore deprecated. CipherSuite TLS_DH_anon_WITH_RC4_128_MD5 = { 0x00,0x18 }; CipherSuite TLS_DH_anon_WITH_DES_CBC_SHA = { 0x00,0x1A }; CipherSuite TLS_DH_anon_WITH_3DES_EDE_CBC_SHA = { 0x00,0x1B }; When SSLv3 and TLS 1.0 were designed, the United States restricted the export of cryptographic software containing certain strong encryption algorithms. A series of cipher suites were designed to operate at reduced key lengths in order to comply with those regulations. Due to advances in computer performance, these algorithms are now unacceptably weak, and export restrictions have since been loosened. TLS 1.1 implementations MUST NOT negotiate these cipher suites in TLS 1.1 mode. However, for backward compatibility they may be offered in the ClientHello for use with TLS
1.0 or SSLv3-only servers. TLS 1.1 clients MUST check that the server did not choose one of these cipher suites during the handshake. These ciphersuites are listed below for informational purposes and to reserve the numbers. CipherSuite TLS_RSA_EXPORT_WITH_RC4_40_MD5 = { 0x00,0x03 }; CipherSuite TLS_RSA_EXPORT_WITH_RC2_CBC_40_MD5 = { 0x00,0x06 }; CipherSuite TLS_RSA_EXPORT_WITH_DES40_CBC_SHA = { 0x00,0x08 }; CipherSuite TLS_DH_DSS_EXPORT_WITH_DES40_CBC_SHA = { 0x00,0x0B }; CipherSuite TLS_DH_RSA_EXPORT_WITH_DES40_CBC_SHA = { 0x00,0x0E }; CipherSuite TLS_DHE_DSS_EXPORT_WITH_DES40_CBC_SHA = { 0x00,0x11 }; CipherSuite TLS_DHE_RSA_EXPORT_WITH_DES40_CBC_SHA = { 0x00,0x14 }; CipherSuite TLS_DH_anon_EXPORT_WITH_RC4_40_MD5 = { 0x00,0x17 }; CipherSuite TLS_DH_anon_EXPORT_WITH_DES40_CBC_SHA = { 0x00,0x19 }; The following cipher suites were defined in [TLSKRB] and are included here for completeness. See [TLSKRB] for details: CipherSuite TLS_KRB5_WITH_DES_CBC_SHA = { 0x00,0x1E }: CipherSuite TLS_KRB5_WITH_3DES_EDE_CBC_SHA = { 0x00,0x1F }; CipherSuite TLS_KRB5_WITH_RC4_128_SHA = { 0x00,0x20 }; CipherSuite TLS_KRB5_WITH_IDEA_CBC_SHA = { 0x00,0x21 }; CipherSuite TLS_KRB5_WITH_DES_CBC_MD5 = { 0x00,0x22 }; CipherSuite TLS_KRB5_WITH_3DES_EDE_CBC_MD5 = { 0x00,0x23 }; CipherSuite TLS_KRB5_WITH_RC4_128_MD5 = { 0x00,0x24 }; CipherSuite TLS_KRB5_WITH_IDEA_CBC_MD5 = { 0x00,0x25 }; The following exportable cipher suites were defined in [TLSKRB] and are included here for completeness. TLS 1.1 implementations MUST NOT negotiate these cipher suites. CipherSuite TLS_KRB5_EXPORT_WITH_DES_CBC_40_SHA = { 0x00,0x26}; CipherSuite TLS_KRB5_EXPORT_WITH_RC2_CBC_40_SHA = { 0x00,0x27}; CipherSuite TLS_KRB5_EXPORT_WITH_RC4_40_SHA = { 0x00,0x28}; CipherSuite TLS_KRB5_EXPORT_WITH_DES_CBC_40_MD5 = { 0x00,0x29}; CipherSuite TLS_KRB5_EXPORT_WITH_RC2_CBC_40_MD5 = { 0x00,0x2A}; CipherSuite TLS_KRB5_EXPORT_WITH_RC4_40_MD5 = { 0x00,0x2B}; The following cipher suites were defined in [TLSAES] and are included here for completeness. See [TLSAES] for details: CipherSuite TLS_RSA_WITH_AES_128_CBC_SHA = { 0x00, 0x2F }; CipherSuite TLS_DH_DSS_WITH_AES_128_CBC_SHA = { 0x00, 0x30 }; CipherSuite TLS_DH_RSA_WITH_AES_128_CBC_SHA = { 0x00, 0x31 }; CipherSuite TLS_DHE_DSS_WITH_AES_128_CBC_SHA = { 0x00, 0x32 }; CipherSuite TLS_DHE_RSA_WITH_AES_128_CBC_SHA = { 0x00, 0x33 }; CipherSuite TLS_DH_anon_WITH_AES_128_CBC_SHA = { 0x00, 0x34 };
CipherSuite TLS_RSA_WITH_AES_256_CBC_SHA = { 0x00, 0x35 }; CipherSuite TLS_DH_DSS_WITH_AES_256_CBC_SHA = { 0x00, 0x36 }; CipherSuite TLS_DH_RSA_WITH_AES_256_CBC_SHA = { 0x00, 0x37 }; CipherSuite TLS_DHE_DSS_WITH_AES_256_CBC_SHA = { 0x00, 0x38 }; CipherSuite TLS_DHE_RSA_WITH_AES_256_CBC_SHA = { 0x00, 0x39 }; CipherSuite TLS_DH_anon_WITH_AES_256_CBC_SHA = { 0x00, 0x3A }; The cipher suite space is divided into three regions: 1. Cipher suite values with first byte 0x00 (zero) through decimal 191 (0xBF) inclusive are reserved for the IETF Standards Track protocols. 2. Cipher suite values with first byte decimal 192 (0xC0) through decimal 254 (0xFE) inclusive are reserved for assignment for non-Standards Track methods. 3. Cipher suite values with first byte 0xFF are reserved for private use. Additional information describing the role of IANA in the allocation of cipher suite code points is described in Section 11. Note: The cipher suite values { 0x00, 0x1C } and { 0x00, 0x1D } are reserved to avoid collision with Fortezza-based cipher suites in SSL 3.A.6. The Security Parameters
These security parameters are determined by the TLS Handshake Protocol and provided as parameters to the TLS Record Layer in order to initialize a connection state. SecurityParameters includes: enum { null(0), (255) } CompressionMethod; enum { server, client } ConnectionEnd; enum { null, rc4, rc2, des, 3des, des40, aes, idea } BulkCipherAlgorithm; enum { stream, block } CipherType; enum { null, md5, sha } MACAlgorithm; /* The algorithms specified in CompressionMethod, BulkCipherAlgorithm, and MACAlgorithm may be added to. */
struct { ConnectionEnd entity; BulkCipherAlgorithm bulk_cipher_algorithm; CipherType cipher_type; uint8 key_size; uint8 key_material_length; MACAlgorithm mac_algorithm; uint8 hash_size; CompressionMethod compression_algorithm; opaque master_secret[48]; opaque client_random[32]; opaque server_random[32]; } SecurityParameters;