mirror of
				https://github.com/cuberite/polarssl.git
				synced 2025-10-30 19:20:40 -04:00 
			
		
		
		
	- Initial bare version of TLS 1.2
This commit is contained in:
		
							parent
							
								
									570267f01a
								
							
						
					
					
						commit
						1ef83d66dd
					
				| @ -34,6 +34,7 @@ | |||||||
| #include "rsa.h" | #include "rsa.h" | ||||||
| #include "md5.h" | #include "md5.h" | ||||||
| #include "sha1.h" | #include "sha1.h" | ||||||
|  | #include "sha2.h" | ||||||
| #include "x509.h" | #include "x509.h" | ||||||
| #include "config.h" | #include "config.h" | ||||||
| 
 | 
 | ||||||
| @ -90,6 +91,7 @@ | |||||||
| #define SSL_MINOR_VERSION_0             0   /*!< SSL v3.0 */ | #define SSL_MINOR_VERSION_0             0   /*!< SSL v3.0 */ | ||||||
| #define SSL_MINOR_VERSION_1             1   /*!< TLS v1.0 */ | #define SSL_MINOR_VERSION_1             1   /*!< TLS v1.0 */ | ||||||
| #define SSL_MINOR_VERSION_2             2   /*!< TLS v1.1 */ | #define SSL_MINOR_VERSION_2             2   /*!< TLS v1.1 */ | ||||||
|  | #define SSL_MINOR_VERSION_3             3   /*!< TLS v1.2 */ | ||||||
| 
 | 
 | ||||||
| #define SSL_IS_CLIENT                   0 | #define SSL_IS_CLIENT                   0 | ||||||
| #define SSL_IS_SERVER                   1 | #define SSL_IS_SERVER                   1 | ||||||
| @ -130,6 +132,19 @@ | |||||||
| #define SSL_RSA_CAMELLIA_256_SHA     0x84 | #define SSL_RSA_CAMELLIA_256_SHA     0x84 | ||||||
| #define SSL_EDH_RSA_CAMELLIA_256_SHA 0x88 | #define SSL_EDH_RSA_CAMELLIA_256_SHA 0x88 | ||||||
| 
 | 
 | ||||||
|  | /*
 | ||||||
|  |  * Supported Signature and Hash algorithms (For TLS 1.2) | ||||||
|  |  */ | ||||||
|  | #define SSL_HASH_NONE                0 | ||||||
|  | #define SSL_HASH_MD5                 1 | ||||||
|  | #define SSL_HASH_SHA1                2 | ||||||
|  | #define SSL_HASH_SHA224              3 | ||||||
|  | #define SSL_HASH_SHA256              4 | ||||||
|  | #define SSL_HASH_SHA384              5 | ||||||
|  | #define SSL_HASH_SHA512              6 | ||||||
|  | 
 | ||||||
|  | #define SSL_SIG_RSA                  1 | ||||||
|  | 
 | ||||||
| /*
 | /*
 | ||||||
|  * Message, alert and handshake types |  * Message, alert and handshake types | ||||||
|  */ |  */ | ||||||
| @ -310,6 +325,12 @@ struct _ssl_context | |||||||
|     dhm_context dhm_ctx;                /*!<  DHM key exchange        */ |     dhm_context dhm_ctx;                /*!<  DHM key exchange        */ | ||||||
|     md5_context fin_md5;                /*!<  Finished MD5 checksum   */ |     md5_context fin_md5;                /*!<  Finished MD5 checksum   */ | ||||||
|     sha1_context fin_sha1;              /*!<  Finished SHA-1 checksum */ |     sha1_context fin_sha1;              /*!<  Finished SHA-1 checksum */ | ||||||
|  |     sha2_context fin_sha2;              /*!<  Finished SHA-256 checksum */ | ||||||
|  | 
 | ||||||
|  |     void (*calc_finished)(ssl_context *, unsigned char *, int); | ||||||
|  |     int  (*tls_prf)(unsigned char *, size_t, char *, | ||||||
|  |                     unsigned char *, size_t, | ||||||
|  |                     unsigned char *, size_t); | ||||||
| 
 | 
 | ||||||
|     int do_crypt;                       /*!<  en(de)cryption flag     */ |     int do_crypt;                       /*!<  en(de)cryption flag     */ | ||||||
|     int *ciphersuites;                  /*!<  allowed ciphersuites    */ |     int *ciphersuites;                  /*!<  allowed ciphersuites    */ | ||||||
| @ -578,7 +599,8 @@ int ssl_set_hostname( ssl_context *ssl, const char *hostname ); | |||||||
|  * \param ssl      SSL context |  * \param ssl      SSL context | ||||||
|  * \param major    Major version number (only SSL_MAJOR_VERSION_3 supported) |  * \param major    Major version number (only SSL_MAJOR_VERSION_3 supported) | ||||||
|  * \param minor    Minor version number (SSL_MINOR_VERSION_0, |  * \param minor    Minor version number (SSL_MINOR_VERSION_0, | ||||||
|  *                 SSL_MINOR_VERSION_1 and SSL_MINOR_VERSION_2 supported) |  *                 SSL_MINOR_VERSION_1 and SSL_MINOR_VERSION_2, | ||||||
|  |  *                 SSL_MINOR_VERSION_3 supported) | ||||||
|  */ |  */ | ||||||
| void ssl_set_max_version( ssl_context *ssl, int major, int minor ); | void ssl_set_max_version( ssl_context *ssl, int major, int minor ); | ||||||
| 
 | 
 | ||||||
|  | |||||||
| @ -113,12 +113,6 @@ int dhm_read_params( dhm_context *ctx, | |||||||
|     if( end - *p < 2 ) |     if( end - *p < 2 ) | ||||||
|         return( POLARSSL_ERR_DHM_BAD_INPUT_DATA ); |         return( POLARSSL_ERR_DHM_BAD_INPUT_DATA ); | ||||||
| 
 | 
 | ||||||
|     n = ( (*p)[0] << 8 ) | (*p)[1]; |  | ||||||
|     (*p) += 2; |  | ||||||
| 
 |  | ||||||
|     if( end != *p + n ) |  | ||||||
|         return( POLARSSL_ERR_DHM_BAD_INPUT_DATA ); |  | ||||||
| 
 |  | ||||||
|     return( 0 ); |     return( 0 ); | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
|  | |||||||
| @ -54,7 +54,7 @@ static int ssl_write_client_hello( ssl_context *ssl ) | |||||||
|     if( ssl->max_major_ver == 0 && ssl->max_minor_ver == 0 ) |     if( ssl->max_major_ver == 0 && ssl->max_minor_ver == 0 ) | ||||||
|     { |     { | ||||||
|         ssl->max_major_ver = SSL_MAJOR_VERSION_3; |         ssl->max_major_ver = SSL_MAJOR_VERSION_3; | ||||||
|         ssl->max_minor_ver = SSL_MINOR_VERSION_2; |         ssl->max_minor_ver = SSL_MINOR_VERSION_3; | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|     /*
 |     /*
 | ||||||
| @ -335,9 +335,11 @@ static int ssl_parse_server_key_exchange( ssl_context *ssl ) | |||||||
|     int ret; |     int ret; | ||||||
|     size_t n; |     size_t n; | ||||||
|     unsigned char *p, *end; |     unsigned char *p, *end; | ||||||
|     unsigned char hash[36]; |     unsigned char hash[64]; | ||||||
|     md5_context md5; |     md5_context md5; | ||||||
|     sha1_context sha1; |     sha1_context sha1; | ||||||
|  |     int hash_id = SIG_RSA_RAW; | ||||||
|  |     unsigned int hashlen; | ||||||
| #endif | #endif | ||||||
| 
 | 
 | ||||||
|     SSL_DEBUG_MSG( 2, ( "=> parse server key exchange" ) ); |     SSL_DEBUG_MSG( 2, ( "=> parse server key exchange" ) ); | ||||||
| @ -376,6 +378,8 @@ static int ssl_parse_server_key_exchange( ssl_context *ssl ) | |||||||
|         return( POLARSSL_ERR_SSL_BAD_HS_SERVER_KEY_EXCHANGE ); |         return( POLARSSL_ERR_SSL_BAD_HS_SERVER_KEY_EXCHANGE ); | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|  |     SSL_DEBUG_BUF( 3,   "server key exchange", ssl->in_msg + 4, ssl->in_hslen - 4 ); | ||||||
|  | 
 | ||||||
|     /*
 |     /*
 | ||||||
|      * Ephemeral DH parameters: |      * Ephemeral DH parameters: | ||||||
|      * |      * | ||||||
| @ -389,6 +393,63 @@ static int ssl_parse_server_key_exchange( ssl_context *ssl ) | |||||||
|     end = ssl->in_msg + ssl->in_hslen; |     end = ssl->in_msg + ssl->in_hslen; | ||||||
| 
 | 
 | ||||||
|     if( ( ret = dhm_read_params( &ssl->dhm_ctx, &p, end ) ) != 0 ) |     if( ( ret = dhm_read_params( &ssl->dhm_ctx, &p, end ) ) != 0 ) | ||||||
|  |     { | ||||||
|  |         SSL_DEBUG_MSG( 2, ( "DHM Read Params returned -0x%x", -ret ) ); | ||||||
|  |         SSL_DEBUG_MSG( 1, ( "bad server key exchange message" ) ); | ||||||
|  |         return( POLARSSL_ERR_SSL_BAD_HS_SERVER_KEY_EXCHANGE );  | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     if( ssl->minor_ver == SSL_MINOR_VERSION_3 ) | ||||||
|  |     { | ||||||
|  |         // TODO TLS 1.2 Check if valid hash and sig
 | ||||||
|  |         if( p[1] != SSL_SIG_RSA ) | ||||||
|  |         { | ||||||
|  |             SSL_DEBUG_MSG( 2, ( "Server used unsupported SignatureAlgorithm %d", p[1] ) ); | ||||||
|  |             SSL_DEBUG_MSG( 1, ( "bad server key exchange message" ) ); | ||||||
|  |             return( POLARSSL_ERR_SSL_BAD_HS_SERVER_KEY_EXCHANGE );  | ||||||
|  |         } | ||||||
|  | 
 | ||||||
|  |         switch( p[0] ) | ||||||
|  |         { | ||||||
|  | #if defined(POLARSSL_MD5_C) | ||||||
|  |             case SSL_HASH_MD5: | ||||||
|  |                 hash_id = SIG_RSA_MD5; | ||||||
|  |                 break; | ||||||
|  | #endif | ||||||
|  | #if defined(POLARSSL_SHA1_C) | ||||||
|  |             case SSL_HASH_SHA1: | ||||||
|  |                 hash_id = SIG_RSA_SHA1; | ||||||
|  |                 break; | ||||||
|  | #endif | ||||||
|  | #if defined(POLARSSL_SHA2_C) | ||||||
|  |             case SSL_HASH_SHA224: | ||||||
|  |                 hash_id = SIG_RSA_SHA224; | ||||||
|  |                 break; | ||||||
|  |             case SSL_HASH_SHA256: | ||||||
|  |                 hash_id = SIG_RSA_SHA256; | ||||||
|  |                 break; | ||||||
|  | #endif | ||||||
|  | #if defined(POLARSSL_SHA4_C) | ||||||
|  |             case SSL_HASH_SHA384: | ||||||
|  |                 hash_id = SIG_RSA_SHA384; | ||||||
|  |                 break; | ||||||
|  |             case SSL_HASH_SHA512: | ||||||
|  |                 hash_id = SIG_RSA_SHA512; | ||||||
|  |                 break; | ||||||
|  | #endif | ||||||
|  |             default: | ||||||
|  |                 SSL_DEBUG_MSG( 2, ( "Server used unsupported HashAlgorithm %d", p[1] ) ); | ||||||
|  |                 SSL_DEBUG_MSG( 1, ( "bad server key exchange message" ) ); | ||||||
|  |                 return( POLARSSL_ERR_SSL_BAD_HS_SERVER_KEY_EXCHANGE );  | ||||||
|  |         }       | ||||||
|  | 
 | ||||||
|  |         p += 2; | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     n = ( p[0] << 8 ) | p[1]; | ||||||
|  |     p += 2; | ||||||
|  | 
 | ||||||
|  |     if( end != p + n ) | ||||||
|     { |     { | ||||||
|         SSL_DEBUG_MSG( 1, ( "bad server key exchange message" ) ); |         SSL_DEBUG_MSG( 1, ( "bad server key exchange message" ) ); | ||||||
|         return( POLARSSL_ERR_SSL_BAD_HS_SERVER_KEY_EXCHANGE ); |         return( POLARSSL_ERR_SSL_BAD_HS_SERVER_KEY_EXCHANGE ); | ||||||
| @ -410,35 +471,61 @@ static int ssl_parse_server_key_exchange( ssl_context *ssl ) | |||||||
|     SSL_DEBUG_MPI( 3, "DHM: G ", &ssl->dhm_ctx.G  ); |     SSL_DEBUG_MPI( 3, "DHM: G ", &ssl->dhm_ctx.G  ); | ||||||
|     SSL_DEBUG_MPI( 3, "DHM: GY", &ssl->dhm_ctx.GY ); |     SSL_DEBUG_MPI( 3, "DHM: GY", &ssl->dhm_ctx.GY ); | ||||||
| 
 | 
 | ||||||
|     /*
 |     if( ssl->minor_ver != SSL_MINOR_VERSION_3 ) | ||||||
|      * digitally-signed struct { |     { | ||||||
|      *     opaque md5_hash[16]; |         /*
 | ||||||
|      *     opaque sha_hash[20]; |          * digitally-signed struct { | ||||||
|      * }; |          *     opaque md5_hash[16]; | ||||||
|      * |          *     opaque sha_hash[20]; | ||||||
|      * md5_hash |          * }; | ||||||
|      *     MD5(ClientHello.random + ServerHello.random |          * | ||||||
|      *                            + ServerParams); |          * md5_hash | ||||||
|      * sha_hash |          *     MD5(ClientHello.random + ServerHello.random | ||||||
|      *     SHA(ClientHello.random + ServerHello.random |          *                            + ServerParams); | ||||||
|      *                            + ServerParams); |          * sha_hash | ||||||
|      */ |          *     SHA(ClientHello.random + ServerHello.random | ||||||
|     n = ssl->in_hslen - ( end - p ) - 6; |          *                            + ServerParams); | ||||||
|  |          */ | ||||||
|  |         n = ssl->in_hslen - ( end - p ) - 6; | ||||||
| 
 | 
 | ||||||
|     md5_starts( &md5 ); |         md5_starts( &md5 ); | ||||||
|     md5_update( &md5, ssl->randbytes, 64 ); |         md5_update( &md5, ssl->randbytes, 64 ); | ||||||
|     md5_update( &md5, ssl->in_msg + 4, n ); |         md5_update( &md5, ssl->in_msg + 4, n ); | ||||||
|     md5_finish( &md5, hash ); |         md5_finish( &md5, hash ); | ||||||
| 
 | 
 | ||||||
|     sha1_starts( &sha1 ); |         sha1_starts( &sha1 ); | ||||||
|     sha1_update( &sha1, ssl->randbytes, 64 ); |         sha1_update( &sha1, ssl->randbytes, 64 ); | ||||||
|     sha1_update( &sha1, ssl->in_msg + 4, n ); |         sha1_update( &sha1, ssl->in_msg + 4, n ); | ||||||
|     sha1_finish( &sha1, hash + 16 ); |         sha1_finish( &sha1, hash + 16 ); | ||||||
| 
 | 
 | ||||||
|     SSL_DEBUG_BUF( 3, "parameters hash", hash, 36 ); |         hash_id = SIG_RSA_RAW; | ||||||
|  |         hashlen = 36; | ||||||
|  |     } | ||||||
|  |     else | ||||||
|  |     { | ||||||
|  |         n = ssl->in_hslen - ( end - p ) - 8; | ||||||
|  | 
 | ||||||
|  |         /*
 | ||||||
|  |          * digitally-signed struct { | ||||||
|  |          *     opaque client_random[32]; | ||||||
|  |          *     opaque server_random[32]; | ||||||
|  |          *     ServerDHParams params; | ||||||
|  |          * }; | ||||||
|  |          */ | ||||||
|  |         /* TODO TLS1.2 Get Hash algorithm from hash and signature extension! */ | ||||||
|  | 
 | ||||||
|  |         sha1_starts( &sha1 ); | ||||||
|  |         sha1_update( &sha1, ssl->randbytes, 64 ); | ||||||
|  |         sha1_update( &sha1, ssl->in_msg + 4, n ); | ||||||
|  |         sha1_finish( &sha1, hash ); | ||||||
|  | 
 | ||||||
|  |         hashlen = 20; | ||||||
|  |     } | ||||||
|  |      | ||||||
|  |     SSL_DEBUG_BUF( 3, "parameters hash", hash, hashlen ); | ||||||
| 
 | 
 | ||||||
|     if( ( ret = rsa_pkcs1_verify( &ssl->peer_cert->rsa, RSA_PUBLIC, |     if( ( ret = rsa_pkcs1_verify( &ssl->peer_cert->rsa, RSA_PUBLIC, | ||||||
|                                   SIG_RSA_RAW, 36, hash, p ) ) != 0 ) |                                   hash_id, hashlen, hash, p ) ) != 0 ) | ||||||
|     { |     { | ||||||
|         SSL_DEBUG_RET( 1, "rsa_pkcs1_verify", ret ); |         SSL_DEBUG_RET( 1, "rsa_pkcs1_verify", ret ); | ||||||
|         return( ret ); |         return( ret ); | ||||||
| @ -643,8 +730,10 @@ static int ssl_write_client_key_exchange( ssl_context *ssl ) | |||||||
| static int ssl_write_certificate_verify( ssl_context *ssl ) | static int ssl_write_certificate_verify( ssl_context *ssl ) | ||||||
| { | { | ||||||
|     int ret = 0; |     int ret = 0; | ||||||
|     size_t n = 0; |     size_t n = 0, offset = 0; | ||||||
|     unsigned char hash[36]; |     unsigned char hash[36]; | ||||||
|  |     int hash_id = SIG_RSA_RAW; | ||||||
|  |     unsigned int hashlen = 36; | ||||||
| 
 | 
 | ||||||
|     SSL_DEBUG_MSG( 2, ( "=> write certificate verify" ) ); |     SSL_DEBUG_MSG( 2, ( "=> write certificate verify" ) ); | ||||||
| 
 | 
 | ||||||
| @ -655,6 +744,12 @@ static int ssl_write_certificate_verify( ssl_context *ssl ) | |||||||
|         return( 0 ); |         return( 0 ); | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|  |     if( ssl->minor_ver == SSL_MINOR_VERSION_3 ) | ||||||
|  |     { | ||||||
|  |         hash_id = SIG_RSA_SHA256; | ||||||
|  |         hashlen = 32; | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|     if( ssl->rsa_key == NULL ) |     if( ssl->rsa_key == NULL ) | ||||||
|     { |     { | ||||||
| #if defined(POLARSSL_PKCS11_C) | #if defined(POLARSSL_PKCS11_C) | ||||||
| @ -680,18 +775,27 @@ static int ssl_write_certificate_verify( ssl_context *ssl ) | |||||||
|         n = ssl->pkcs11_key->len; |         n = ssl->pkcs11_key->len; | ||||||
| #endif  /* defined(POLARSSL_PKCS11_C) */ | #endif  /* defined(POLARSSL_PKCS11_C) */ | ||||||
| 
 | 
 | ||||||
|     ssl->out_msg[4] = (unsigned char)( n >> 8 ); |     if( ssl->minor_ver == SSL_MINOR_VERSION_3 ) | ||||||
|     ssl->out_msg[5] = (unsigned char)( n      ); |     { | ||||||
|  |         // TODO TLS1.2 Base on signature algorithm extension received
 | ||||||
|  |         ssl->out_msg[4] = SSL_HASH_SHA1; | ||||||
|  |         ssl->out_msg[5] = SSL_SIG_RSA; | ||||||
|  | 
 | ||||||
|  |         offset = 2; | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     ssl->out_msg[4 + offset] = (unsigned char)( n >> 8 ); | ||||||
|  |     ssl->out_msg[5 + offset] = (unsigned char)( n      ); | ||||||
| 
 | 
 | ||||||
|     if( ssl->rsa_key ) |     if( ssl->rsa_key ) | ||||||
|     { |     { | ||||||
|         ret = rsa_pkcs1_sign( ssl->rsa_key, ssl->f_rng, ssl->p_rng, |         ret = rsa_pkcs1_sign( ssl->rsa_key, ssl->f_rng, ssl->p_rng, | ||||||
|                                     RSA_PRIVATE, SIG_RSA_RAW, |                                    RSA_PRIVATE, hash_id, | ||||||
|                                     36, hash, ssl->out_msg + 6 ); |                                    hashlen, hash, ssl->out_msg + 6 + offset ); | ||||||
|     } else { |     } else { | ||||||
| #if defined(POLARSSL_PKCS11_C) | #if defined(POLARSSL_PKCS11_C) | ||||||
|         ret = pkcs11_sign( ssl->pkcs11_key, RSA_PRIVATE, SIG_RSA_RAW, |         ret = pkcs11_sign( ssl->pkcs11_key, RSA_PRIVATE, hash_id, | ||||||
|                                     36, hash, ssl->out_msg + 6 ); |                                     hashlen, hash, ssl->out_msg + 6 + offset ); | ||||||
| #endif  /* defined(POLARSSL_PKCS11_C) */ | #endif  /* defined(POLARSSL_PKCS11_C) */ | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
| @ -701,7 +805,7 @@ static int ssl_write_certificate_verify( ssl_context *ssl ) | |||||||
|         return( ret ); |         return( ret ); | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|     ssl->out_msglen  = 6 + n; |     ssl->out_msglen  = 6 + n + offset; | ||||||
|     ssl->out_msgtype = SSL_MSG_HANDSHAKE; |     ssl->out_msgtype = SSL_MSG_HANDSHAKE; | ||||||
|     ssl->out_msg[0]  = SSL_HS_CERTIFICATE_VERIFY; |     ssl->out_msg[0]  = SSL_HS_CERTIFICATE_VERIFY; | ||||||
| 
 | 
 | ||||||
|  | |||||||
| @ -97,8 +97,8 @@ static int ssl_parse_client_hello( ssl_context *ssl ) | |||||||
|         ssl->max_minor_ver = buf[4]; |         ssl->max_minor_ver = buf[4]; | ||||||
| 
 | 
 | ||||||
|         ssl->major_ver = SSL_MAJOR_VERSION_3; |         ssl->major_ver = SSL_MAJOR_VERSION_3; | ||||||
|         ssl->minor_ver = ( buf[4] <= SSL_MINOR_VERSION_2 ) |         ssl->minor_ver = ( buf[4] <= SSL_MINOR_VERSION_3 ) | ||||||
|                          ? buf[4]  : SSL_MINOR_VERSION_2; |                          ? buf[4]  : SSL_MINOR_VERSION_3; | ||||||
| 
 | 
 | ||||||
|         if( ( ret = ssl_fetch_input( ssl, 2 + n ) ) != 0 ) |         if( ( ret = ssl_fetch_input( ssl, 2 + n ) ) != 0 ) | ||||||
|         { |         { | ||||||
| @ -108,6 +108,7 @@ static int ssl_parse_client_hello( ssl_context *ssl ) | |||||||
| 
 | 
 | ||||||
|          md5_update( &ssl->fin_md5 , buf + 2, n ); |          md5_update( &ssl->fin_md5 , buf + 2, n ); | ||||||
|         sha1_update( &ssl->fin_sha1, buf + 2, n ); |         sha1_update( &ssl->fin_sha1, buf + 2, n ); | ||||||
|  |         sha2_update( &ssl->fin_sha2, buf + 2, n ); | ||||||
| 
 | 
 | ||||||
|         buf = ssl->in_msg; |         buf = ssl->in_msg; | ||||||
|         n = ssl->in_left - 5; |         n = ssl->in_left - 5; | ||||||
| @ -228,6 +229,7 @@ static int ssl_parse_client_hello( ssl_context *ssl ) | |||||||
| 
 | 
 | ||||||
|          md5_update( &ssl->fin_md5 , buf, n ); |          md5_update( &ssl->fin_md5 , buf, n ); | ||||||
|         sha1_update( &ssl->fin_sha1, buf, n ); |         sha1_update( &ssl->fin_sha1, buf, n ); | ||||||
|  |         sha2_update( &ssl->fin_sha2, buf, n ); | ||||||
| 
 | 
 | ||||||
|         /*
 |         /*
 | ||||||
|          * SSL layer: |          * SSL layer: | ||||||
| @ -263,8 +265,8 @@ static int ssl_parse_client_hello( ssl_context *ssl ) | |||||||
|         } |         } | ||||||
| 
 | 
 | ||||||
|         ssl->major_ver = SSL_MAJOR_VERSION_3; |         ssl->major_ver = SSL_MAJOR_VERSION_3; | ||||||
|         ssl->minor_ver = ( buf[5] <= SSL_MINOR_VERSION_2 ) |         ssl->minor_ver = ( buf[5] <= SSL_MINOR_VERSION_3 ) | ||||||
|                          ? buf[5]  : SSL_MINOR_VERSION_2; |                          ? buf[5]  : SSL_MINOR_VERSION_3; | ||||||
| 
 | 
 | ||||||
|         ssl->max_major_ver = buf[4]; |         ssl->max_major_ver = buf[4]; | ||||||
|         ssl->max_minor_ver = buf[5]; |         ssl->max_minor_ver = buf[5]; | ||||||
| @ -540,6 +542,8 @@ static int ssl_write_server_key_exchange( ssl_context *ssl ) | |||||||
|     unsigned char hash[36]; |     unsigned char hash[36]; | ||||||
|     md5_context md5; |     md5_context md5; | ||||||
|     sha1_context sha1; |     sha1_context sha1; | ||||||
|  |     int hash_id; | ||||||
|  |     unsigned int hashlen; | ||||||
| #endif | #endif | ||||||
| 
 | 
 | ||||||
|     SSL_DEBUG_MSG( 2, ( "=> write server key exchange" ) ); |     SSL_DEBUG_MSG( 2, ( "=> write server key exchange" ) ); | ||||||
| @ -595,30 +599,55 @@ static int ssl_write_server_key_exchange( ssl_context *ssl ) | |||||||
|     SSL_DEBUG_MPI( 3, "DHM: G ", &ssl->dhm_ctx.G  ); |     SSL_DEBUG_MPI( 3, "DHM: G ", &ssl->dhm_ctx.G  ); | ||||||
|     SSL_DEBUG_MPI( 3, "DHM: GX", &ssl->dhm_ctx.GX ); |     SSL_DEBUG_MPI( 3, "DHM: GX", &ssl->dhm_ctx.GX ); | ||||||
| 
 | 
 | ||||||
|     /*
 |     if( ssl->minor_ver != SSL_MINOR_VERSION_3 ) | ||||||
|      * digitally-signed struct { |     { | ||||||
|      *     opaque md5_hash[16]; |         /*
 | ||||||
|      *     opaque sha_hash[20]; |          * digitally-signed struct { | ||||||
|      * }; |          *     opaque md5_hash[16]; | ||||||
|      * |          *     opaque sha_hash[20]; | ||||||
|      * md5_hash |          * }; | ||||||
|      *     MD5(ClientHello.random + ServerHello.random |          * | ||||||
|      *                            + ServerParams); |          * md5_hash | ||||||
|      * sha_hash |          *     MD5(ClientHello.random + ServerHello.random | ||||||
|      *     SHA(ClientHello.random + ServerHello.random |          *                            + ServerParams); | ||||||
|      *                            + ServerParams); |          * sha_hash | ||||||
|      */ |          *     SHA(ClientHello.random + ServerHello.random | ||||||
|     md5_starts( &md5 ); |          *                            + ServerParams); | ||||||
|     md5_update( &md5, ssl->randbytes,  64 ); |          */ | ||||||
|     md5_update( &md5, ssl->out_msg + 4, n ); |         md5_starts( &md5 ); | ||||||
|     md5_finish( &md5, hash ); |         md5_update( &md5, ssl->randbytes,  64 ); | ||||||
|  |         md5_update( &md5, ssl->out_msg + 4, n ); | ||||||
|  |         md5_finish( &md5, hash ); | ||||||
| 
 | 
 | ||||||
|     sha1_starts( &sha1 ); |         sha1_starts( &sha1 ); | ||||||
|     sha1_update( &sha1, ssl->randbytes,  64 ); |         sha1_update( &sha1, ssl->randbytes,  64 ); | ||||||
|     sha1_update( &sha1, ssl->out_msg + 4, n ); |         sha1_update( &sha1, ssl->out_msg + 4, n ); | ||||||
|     sha1_finish( &sha1, hash + 16 ); |         sha1_finish( &sha1, hash + 16 ); | ||||||
| 
 | 
 | ||||||
|     SSL_DEBUG_BUF( 3, "parameters hash", hash, 36 ); |         hashlen = 36; | ||||||
|  |         hash_id = SIG_RSA_RAW; | ||||||
|  |     } | ||||||
|  |     else | ||||||
|  |     { | ||||||
|  |         /*
 | ||||||
|  |          * digitally-signed struct { | ||||||
|  |          *     opaque client_random[32]; | ||||||
|  |          *     opaque server_random[32]; | ||||||
|  |          *     ServerDHParams params; | ||||||
|  |          * }; | ||||||
|  |          */ | ||||||
|  |         /* TODO TLS1.2 Get Hash algorithm from ciphersuite! */ | ||||||
|  |       | ||||||
|  |         sha1_starts( &sha1 ); | ||||||
|  |         sha1_update( &sha1, ssl->randbytes, 64 ); | ||||||
|  |         sha1_update( &sha1, ssl->out_msg + 4, n ); | ||||||
|  |         sha1_finish( &sha1, hash ); | ||||||
|  | 
 | ||||||
|  |         hashlen = 20; | ||||||
|  |         hash_id = SIG_RSA_SHA1; | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     SSL_DEBUG_BUF( 3, "parameters hash", hash, hashlen ); | ||||||
| 
 | 
 | ||||||
|     if ( ssl->rsa_key ) |     if ( ssl->rsa_key ) | ||||||
|         rsa_key_len = ssl->rsa_key->len; |         rsa_key_len = ssl->rsa_key->len; | ||||||
| @ -627,6 +656,15 @@ static int ssl_write_server_key_exchange( ssl_context *ssl ) | |||||||
|         rsa_key_len = ssl->pkcs11_key->len; |         rsa_key_len = ssl->pkcs11_key->len; | ||||||
| #endif /* defined(POLARSSL_PKCS11_C) */ | #endif /* defined(POLARSSL_PKCS11_C) */ | ||||||
| 
 | 
 | ||||||
|  |     if( ssl->minor_ver == SSL_MINOR_VERSION_3 ) | ||||||
|  |     { | ||||||
|  |         // TODO TLS1.2 Base on signature algorithm extension received
 | ||||||
|  |         ssl->out_msg[4 + n] = SSL_HASH_SHA1; | ||||||
|  |         ssl->out_msg[5 + n] = SSL_SIG_RSA; | ||||||
|  | 
 | ||||||
|  |         n += 2; | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|     ssl->out_msg[4 + n] = (unsigned char)( rsa_key_len >> 8 ); |     ssl->out_msg[4 + n] = (unsigned char)( rsa_key_len >> 8 ); | ||||||
|     ssl->out_msg[5 + n] = (unsigned char)( rsa_key_len      ); |     ssl->out_msg[5 + n] = (unsigned char)( rsa_key_len      ); | ||||||
| 
 | 
 | ||||||
| @ -634,12 +672,12 @@ static int ssl_write_server_key_exchange( ssl_context *ssl ) | |||||||
|     { |     { | ||||||
|         ret = rsa_pkcs1_sign( ssl->rsa_key, ssl->f_rng, ssl->p_rng, |         ret = rsa_pkcs1_sign( ssl->rsa_key, ssl->f_rng, ssl->p_rng, | ||||||
|                               RSA_PRIVATE, |                               RSA_PRIVATE, | ||||||
|                               SIG_RSA_RAW, 36, hash, ssl->out_msg + 6 + n ); |                               hash_id, hashlen, hash, ssl->out_msg + 6 + n ); | ||||||
|     } |     } | ||||||
| #if defined(POLARSSL_PKCS11_C) | #if defined(POLARSSL_PKCS11_C) | ||||||
|     else { |     else { | ||||||
|         ret = pkcs11_sign( ssl->pkcs11_key, RSA_PRIVATE, |         ret = pkcs11_sign( ssl->pkcs11_key, RSA_PRIVATE, | ||||||
|                               SIG_RSA_RAW, 36, hash, ssl->out_msg + 6 + n ); |                               hash_id, hashlen, hash, ssl->out_msg + 6 + n ); | ||||||
|     } |     } | ||||||
| #endif  /* defined(POLARSSL_PKCS11_C) */ | #endif  /* defined(POLARSSL_PKCS11_C) */ | ||||||
| 
 | 
 | ||||||
|  | |||||||
| @ -113,6 +113,49 @@ static int tls1_prf( unsigned char *secret, size_t slen, char *label, | |||||||
|     return( 0 ); |     return( 0 ); | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
|  | static int tls_prf_sha256( unsigned char *secret, size_t slen, char *label, | ||||||
|  |                            unsigned char *random, size_t rlen, | ||||||
|  |                            unsigned char *dstbuf, size_t dlen ) | ||||||
|  | { | ||||||
|  |     size_t nb; | ||||||
|  |     size_t i, j, k; | ||||||
|  |     unsigned char tmp[128]; | ||||||
|  |     unsigned char h_i[32]; | ||||||
|  | 
 | ||||||
|  |     if( sizeof( tmp ) < 32 + strlen( label ) + rlen ) | ||||||
|  |         return( POLARSSL_ERR_SSL_BAD_INPUT_DATA ); | ||||||
|  | 
 | ||||||
|  |     nb = strlen( label ); | ||||||
|  |     memcpy( tmp + 32, label, nb ); | ||||||
|  |     memcpy( tmp + 32 + nb, random, rlen ); | ||||||
|  |     nb += rlen; | ||||||
|  | 
 | ||||||
|  |     /*
 | ||||||
|  |      * Compute P_<hash>(secret, label + random)[0..dlen] | ||||||
|  |      */ | ||||||
|  |     sha2_hmac( secret, slen, tmp + 32, nb, tmp, 0 ); | ||||||
|  | 
 | ||||||
|  |     for( i = 0; i < dlen; i += 32 ) | ||||||
|  |     { | ||||||
|  |         sha2_hmac( secret, slen, tmp, 32 + nb, h_i, 0 ); | ||||||
|  |         sha2_hmac( secret, slen, tmp, 32,      tmp, 0 ); | ||||||
|  | 
 | ||||||
|  |         k = ( i + 32 > dlen ) ? dlen % 32 : 32; | ||||||
|  | 
 | ||||||
|  |         for( j = 0; j < k; j++ ) | ||||||
|  |             dstbuf[i + j]  = h_i[j]; | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     memset( tmp, 0, sizeof( tmp ) ); | ||||||
|  |     memset( h_i, 0, sizeof( h_i ) ); | ||||||
|  | 
 | ||||||
|  |     return( 0 ); | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | static void ssl_calc_finished_ssl   (ssl_context *,unsigned char *,int); | ||||||
|  | static void ssl_calc_finished_tls   (ssl_context *,unsigned char *,int); | ||||||
|  | static void ssl_calc_finished_tls1_2(ssl_context *,unsigned char *,int); | ||||||
|  | 
 | ||||||
| int ssl_derive_keys( ssl_context *ssl ) | int ssl_derive_keys( ssl_context *ssl ) | ||||||
| { | { | ||||||
|     int i; |     int i; | ||||||
| @ -127,6 +170,24 @@ int ssl_derive_keys( ssl_context *ssl ) | |||||||
| 
 | 
 | ||||||
|     SSL_DEBUG_MSG( 2, ( "=> derive keys" ) ); |     SSL_DEBUG_MSG( 2, ( "=> derive keys" ) ); | ||||||
| 
 | 
 | ||||||
|  |     /*
 | ||||||
|  |      * Set appropriate PRF function. | ||||||
|  |      */ | ||||||
|  |     if( ssl->minor_ver < SSL_MINOR_VERSION_3 ) | ||||||
|  |         ssl->tls_prf = tls1_prf; | ||||||
|  |     else | ||||||
|  |         ssl->tls_prf = tls_prf_sha256; | ||||||
|  | 
 | ||||||
|  |     /*
 | ||||||
|  |      * Set appropriate SSL / TLS / TLS1.2 functions | ||||||
|  |      */ | ||||||
|  |     if( ssl->minor_ver == SSL_MINOR_VERSION_0 ) | ||||||
|  |         ssl->calc_finished = ssl_calc_finished_ssl; | ||||||
|  |     else if( ssl->minor_ver < SSL_MINOR_VERSION_3 ) | ||||||
|  |         ssl->calc_finished = ssl_calc_finished_tls; | ||||||
|  |     else | ||||||
|  |         ssl->calc_finished = ssl_calc_finished_tls1_2; | ||||||
|  | 
 | ||||||
|     /*
 |     /*
 | ||||||
|      * SSLv3: |      * SSLv3: | ||||||
|      *   master = |      *   master = | ||||||
| @ -162,8 +223,8 @@ int ssl_derive_keys( ssl_context *ssl ) | |||||||
|             } |             } | ||||||
|         } |         } | ||||||
|         else  |         else  | ||||||
|             tls1_prf( ssl->premaster, len, "master secret", |             ssl->tls_prf( ssl->premaster, len, "master secret", | ||||||
|                       ssl->randbytes, 64, ssl->session->master, 48 ); |                           ssl->randbytes, 64, ssl->session->master, 48 ); | ||||||
| 
 | 
 | ||||||
|         memset( ssl->premaster, 0, sizeof( ssl->premaster ) ); |         memset( ssl->premaster, 0, sizeof( ssl->premaster ) ); | ||||||
|     } |     } | ||||||
| @ -215,8 +276,8 @@ int ssl_derive_keys( ssl_context *ssl ) | |||||||
|         memset( sha1sum, 0, sizeof( sha1sum ) ); |         memset( sha1sum, 0, sizeof( sha1sum ) ); | ||||||
|     } |     } | ||||||
|     else |     else | ||||||
|         tls1_prf( ssl->session->master, 48, "key expansion", |         ssl->tls_prf( ssl->session->master, 48, "key expansion", | ||||||
|                   ssl->randbytes, 64, keyblk, 256 ); |                       ssl->randbytes, 64, keyblk, 256 ); | ||||||
| 
 | 
 | ||||||
|     SSL_DEBUG_MSG( 3, ( "ciphersuite = %s", ssl_get_ciphersuite( ssl ) ) ); |     SSL_DEBUG_MSG( 3, ( "ciphersuite = %s", ssl_get_ciphersuite( ssl ) ) ); | ||||||
|     SSL_DEBUG_BUF( 3, "master secret", ssl->session->master, 48 ); |     SSL_DEBUG_BUF( 3, "master secret", ssl->session->master, 48 ); | ||||||
| @ -426,6 +487,7 @@ void ssl_calc_verify( ssl_context *ssl, unsigned char hash[36] ) | |||||||
| { | { | ||||||
|     md5_context md5; |     md5_context md5; | ||||||
|     sha1_context sha1; |     sha1_context sha1; | ||||||
|  |     sha2_context sha2; | ||||||
|     unsigned char pad_1[48]; |     unsigned char pad_1[48]; | ||||||
|     unsigned char pad_2[48]; |     unsigned char pad_2[48]; | ||||||
| 
 | 
 | ||||||
| @ -433,6 +495,7 @@ void ssl_calc_verify( ssl_context *ssl, unsigned char hash[36] ) | |||||||
| 
 | 
 | ||||||
|     memcpy( &md5 , &ssl->fin_md5 , sizeof(  md5_context ) ); |     memcpy( &md5 , &ssl->fin_md5 , sizeof(  md5_context ) ); | ||||||
|     memcpy( &sha1, &ssl->fin_sha1, sizeof( sha1_context ) ); |     memcpy( &sha1, &ssl->fin_sha1, sizeof( sha1_context ) ); | ||||||
|  |     memcpy( &sha2, &ssl->fin_sha2, sizeof( sha2_context ) ); | ||||||
| 
 | 
 | ||||||
|     if( ssl->minor_ver == SSL_MINOR_VERSION_0 ) |     if( ssl->minor_ver == SSL_MINOR_VERSION_0 ) | ||||||
|     { |     { | ||||||
| @ -459,11 +522,15 @@ void ssl_calc_verify( ssl_context *ssl, unsigned char hash[36] ) | |||||||
|         sha1_update( &sha1, hash + 16, 20 ); |         sha1_update( &sha1, hash + 16, 20 ); | ||||||
|         sha1_finish( &sha1, hash + 16 ); |         sha1_finish( &sha1, hash + 16 ); | ||||||
|     } |     } | ||||||
|     else /* TLSv1 */ |     else if( ssl->minor_ver != SSL_MINOR_VERSION_3 ) /* TLSv1 */ | ||||||
|     { |     { | ||||||
|          md5_finish( &md5,  hash ); |          md5_finish( &md5,  hash ); | ||||||
|         sha1_finish( &sha1, hash + 16 ); |         sha1_finish( &sha1, hash + 16 ); | ||||||
|     } |     } | ||||||
|  |     else | ||||||
|  |     { | ||||||
|  |         sha2_finish( &sha2, hash ); | ||||||
|  |     } | ||||||
| 
 | 
 | ||||||
|     SSL_DEBUG_BUF( 3, "calculated verify result", hash, 36 ); |     SSL_DEBUG_BUF( 3, "calculated verify result", hash, 36 ); | ||||||
|     SSL_DEBUG_MSG( 2, ( "<= calc verify" ) ); |     SSL_DEBUG_MSG( 2, ( "<= calc verify" ) ); | ||||||
| @ -630,10 +697,10 @@ static int ssl_encrypt_buf( ssl_context *ssl ) | |||||||
|         enc_msg = ssl->out_msg; |         enc_msg = ssl->out_msg; | ||||||
| 
 | 
 | ||||||
|         /*
 |         /*
 | ||||||
|          * Prepend per-record IV for block cipher in TLS v1.1 as per |          * Prepend per-record IV for block cipher in TLS v1.1 and up as per | ||||||
|          * Method 1 (6.2.3.2. in RFC4346) |          * Method 1 (6.2.3.2. in RFC4346 and RFC5246) | ||||||
|          */ |          */ | ||||||
|         if( ssl->minor_ver == SSL_MINOR_VERSION_2 ) |         if( ssl->minor_ver >= SSL_MINOR_VERSION_2 ) | ||||||
|         { |         { | ||||||
|             /*
 |             /*
 | ||||||
|              * Generate IV |              * Generate IV | ||||||
| @ -781,9 +848,9 @@ static int ssl_decrypt_buf( ssl_context *ssl ) | |||||||
|         dec_msg_result = ssl->in_msg; |         dec_msg_result = ssl->in_msg; | ||||||
| 
 | 
 | ||||||
|         /*
 |         /*
 | ||||||
|          * Initialize for prepended IV for block cipher in TLS v1.1 |          * Initialize for prepended IV for block cipher in TLS v1.1 and up | ||||||
|          */ |          */ | ||||||
|         if( ssl->minor_ver == SSL_MINOR_VERSION_2 ) |         if( ssl->minor_ver >= SSL_MINOR_VERSION_2 ) | ||||||
|         { |         { | ||||||
|             dec_msg += ssl->ivlen; |             dec_msg += ssl->ivlen; | ||||||
|             dec_msglen -= ssl->ivlen; |             dec_msglen -= ssl->ivlen; | ||||||
| @ -1053,6 +1120,7 @@ int ssl_write_record( ssl_context *ssl ) | |||||||
| 
 | 
 | ||||||
|          md5_update( &ssl->fin_md5 , ssl->out_msg, len ); |          md5_update( &ssl->fin_md5 , ssl->out_msg, len ); | ||||||
|         sha1_update( &ssl->fin_sha1, ssl->out_msg, len ); |         sha1_update( &ssl->fin_sha1, ssl->out_msg, len ); | ||||||
|  |         sha2_update( &ssl->fin_sha2, ssl->out_msg, len ); | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|     if( ssl->do_crypt != 0 ) |     if( ssl->do_crypt != 0 ) | ||||||
| @ -1127,6 +1195,7 @@ int ssl_read_record( ssl_context *ssl ) | |||||||
| 
 | 
 | ||||||
|          md5_update( &ssl->fin_md5 , ssl->in_msg, ssl->in_hslen ); |          md5_update( &ssl->fin_md5 , ssl->in_msg, ssl->in_hslen ); | ||||||
|         sha1_update( &ssl->fin_sha1, ssl->in_msg, ssl->in_hslen ); |         sha1_update( &ssl->fin_sha1, ssl->in_msg, ssl->in_hslen ); | ||||||
|  |         sha2_update( &ssl->fin_sha2, ssl->in_msg, ssl->in_hslen ); | ||||||
| 
 | 
 | ||||||
|         return( 0 ); |         return( 0 ); | ||||||
|     } |     } | ||||||
| @ -1192,7 +1261,7 @@ int ssl_read_record( ssl_context *ssl ) | |||||||
|         /*
 |         /*
 | ||||||
|          * TLS encrypted messages can have up to 256 bytes of padding |          * TLS encrypted messages can have up to 256 bytes of padding | ||||||
|          */ |          */ | ||||||
|         if( ssl->minor_ver == SSL_MINOR_VERSION_1 && |         if( ssl->minor_ver >= SSL_MINOR_VERSION_1 && | ||||||
|             ssl->in_msglen > ssl->minlen + SSL_MAX_CONTENT_LEN + 256 ) |             ssl->in_msglen > ssl->minlen + SSL_MAX_CONTENT_LEN + 256 ) | ||||||
|         { |         { | ||||||
|             SSL_DEBUG_MSG( 1, ( "bad message length" ) ); |             SSL_DEBUG_MSG( 1, ( "bad message length" ) ); | ||||||
| @ -1256,6 +1325,7 @@ int ssl_read_record( ssl_context *ssl ) | |||||||
| 
 | 
 | ||||||
|          md5_update( &ssl->fin_md5 , ssl->in_msg, ssl->in_hslen ); |          md5_update( &ssl->fin_md5 , ssl->in_msg, ssl->in_hslen ); | ||||||
|         sha1_update( &ssl->fin_sha1, ssl->in_msg, ssl->in_hslen ); |         sha1_update( &ssl->fin_sha1, ssl->in_msg, ssl->in_hslen ); | ||||||
|  |         sha2_update( &ssl->fin_sha2, ssl->in_msg, ssl->in_hslen ); | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|     if( ssl->in_msgtype == SSL_MSG_ALERT ) |     if( ssl->in_msgtype == SSL_MSG_ALERT ) | ||||||
| @ -1600,17 +1670,21 @@ int ssl_parse_change_cipher_spec( ssl_context *ssl ) | |||||||
|     return( 0 ); |     return( 0 ); | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| static void ssl_calc_finished( | static void ssl_calc_finished_ssl( | ||||||
|                 ssl_context *ssl, unsigned char *buf, int from, |                 ssl_context *ssl, unsigned char *buf, int from ) | ||||||
|                 md5_context *md5, sha1_context *sha1 ) |  | ||||||
| { | { | ||||||
|     int len = 12; |  | ||||||
|     char *sender; |     char *sender; | ||||||
|  |     md5_context  md5; | ||||||
|  |     sha1_context sha1; | ||||||
|  | 
 | ||||||
|     unsigned char padbuf[48]; |     unsigned char padbuf[48]; | ||||||
|     unsigned char md5sum[16]; |     unsigned char md5sum[16]; | ||||||
|     unsigned char sha1sum[20]; |     unsigned char sha1sum[20]; | ||||||
| 
 | 
 | ||||||
|     SSL_DEBUG_MSG( 2, ( "=> calc  finished" ) ); |     SSL_DEBUG_MSG( 2, ( "=> calc  finished ssl" ) ); | ||||||
|  | 
 | ||||||
|  |     memcpy( &md5 , &ssl->fin_md5 , sizeof(  md5_context ) ); | ||||||
|  |     memcpy( &sha1, &ssl->fin_sha1, sizeof( sha1_context ) ); | ||||||
| 
 | 
 | ||||||
|     /*
 |     /*
 | ||||||
|      * SSLv3: |      * SSLv3: | ||||||
| @ -1619,68 +1693,47 @@ static void ssl_calc_finished( | |||||||
|      *          MD5( handshake + sender + master + pad1 ) ) |      *          MD5( handshake + sender + master + pad1 ) ) | ||||||
|      *   + SHA1( master + pad2 + |      *   + SHA1( master + pad2 + | ||||||
|      *         SHA1( handshake + sender + master + pad1 ) ) |      *         SHA1( handshake + sender + master + pad1 ) ) | ||||||
|      * |  | ||||||
|      * TLSv1: |  | ||||||
|      *   hash = PRF( master, finished_label, |  | ||||||
|      *               MD5( handshake ) + SHA1( handshake ) )[0..11] |  | ||||||
|      */ |      */ | ||||||
| 
 | 
 | ||||||
|     SSL_DEBUG_BUF( 4, "finished  md5 state", (unsigned char *) |     SSL_DEBUG_BUF( 4, "finished  md5 state", (unsigned char *) | ||||||
|                     md5->state, sizeof(  md5->state ) ); |                     md5.state, sizeof(  md5.state ) ); | ||||||
| 
 | 
 | ||||||
|     SSL_DEBUG_BUF( 4, "finished sha1 state", (unsigned char *) |     SSL_DEBUG_BUF( 4, "finished sha1 state", (unsigned char *) | ||||||
|                    sha1->state, sizeof( sha1->state ) ); |                    sha1.state, sizeof( sha1.state ) ); | ||||||
| 
 | 
 | ||||||
|     if( ssl->minor_ver == SSL_MINOR_VERSION_0 ) |     sender = ( from == SSL_IS_CLIENT ) ? (char *) "CLNT" | ||||||
|     { |                                        : (char *) "SRVR"; | ||||||
|         sender = ( from == SSL_IS_CLIENT ) ? (char *) "CLNT" |  | ||||||
|                                            : (char *) "SRVR"; |  | ||||||
| 
 | 
 | ||||||
|         memset( padbuf, 0x36, 48 ); |     memset( padbuf, 0x36, 48 ); | ||||||
| 
 | 
 | ||||||
|         md5_update( md5, (unsigned char *) sender, 4 ); |     md5_update( &md5, (unsigned char *) sender, 4 ); | ||||||
|         md5_update( md5, ssl->session->master, 48 ); |     md5_update( &md5, ssl->session->master, 48 ); | ||||||
|         md5_update( md5, padbuf, 48 ); |     md5_update( &md5, padbuf, 48 ); | ||||||
|         md5_finish( md5, md5sum ); |     md5_finish( &md5, md5sum ); | ||||||
| 
 | 
 | ||||||
|         sha1_update( sha1, (unsigned char *) sender, 4 ); |     sha1_update( &sha1, (unsigned char *) sender, 4 ); | ||||||
|         sha1_update( sha1, ssl->session->master, 48 ); |     sha1_update( &sha1, ssl->session->master, 48 ); | ||||||
|         sha1_update( sha1, padbuf, 40 ); |     sha1_update( &sha1, padbuf, 40 ); | ||||||
|         sha1_finish( sha1, sha1sum ); |     sha1_finish( &sha1, sha1sum ); | ||||||
| 
 | 
 | ||||||
|         memset( padbuf, 0x5C, 48 ); |     memset( padbuf, 0x5C, 48 ); | ||||||
| 
 | 
 | ||||||
|         md5_starts( md5 ); |     md5_starts( &md5 ); | ||||||
|         md5_update( md5, ssl->session->master, 48 ); |     md5_update( &md5, ssl->session->master, 48 ); | ||||||
|         md5_update( md5, padbuf, 48 ); |     md5_update( &md5, padbuf, 48 ); | ||||||
|         md5_update( md5, md5sum, 16 ); |     md5_update( &md5, md5sum, 16 ); | ||||||
|         md5_finish( md5, buf ); |     md5_finish( &md5, buf ); | ||||||
| 
 | 
 | ||||||
|         sha1_starts( sha1 ); |     sha1_starts( &sha1 ); | ||||||
|         sha1_update( sha1, ssl->session->master, 48 ); |     sha1_update( &sha1, ssl->session->master, 48 ); | ||||||
|         sha1_update( sha1, padbuf , 40 ); |     sha1_update( &sha1, padbuf , 40 ); | ||||||
|         sha1_update( sha1, sha1sum, 20 ); |     sha1_update( &sha1, sha1sum, 20 ); | ||||||
|         sha1_finish( sha1, buf + 16 ); |     sha1_finish( &sha1, buf + 16 ); | ||||||
| 
 | 
 | ||||||
|         len += 24; |     SSL_DEBUG_BUF( 3, "calc finished result", buf, 36 ); | ||||||
|     } |  | ||||||
|     else |  | ||||||
|     { |  | ||||||
|         sender = ( from == SSL_IS_CLIENT ) |  | ||||||
|                  ? (char *) "client finished" |  | ||||||
|                  : (char *) "server finished"; |  | ||||||
| 
 | 
 | ||||||
|          md5_finish(  md5, padbuf ); |     memset(  &md5, 0, sizeof(  md5_context ) ); | ||||||
|         sha1_finish( sha1, padbuf + 16 ); |     memset( &sha1, 0, sizeof( sha1_context ) ); | ||||||
| 
 |  | ||||||
|         tls1_prf( ssl->session->master, 48, sender, |  | ||||||
|                   padbuf, 36, buf, len ); |  | ||||||
|     } |  | ||||||
| 
 |  | ||||||
|     SSL_DEBUG_BUF( 3, "calc finished result", buf, len ); |  | ||||||
| 
 |  | ||||||
|     memset(  md5, 0, sizeof(  md5_context ) ); |  | ||||||
|     memset( sha1, 0, sizeof( sha1_context ) ); |  | ||||||
| 
 | 
 | ||||||
|     memset(  padbuf, 0, sizeof(  padbuf ) ); |     memset(  padbuf, 0, sizeof(  padbuf ) ); | ||||||
|     memset(  md5sum, 0, sizeof(  md5sum ) ); |     memset(  md5sum, 0, sizeof(  md5sum ) ); | ||||||
| @ -1689,20 +1742,100 @@ static void ssl_calc_finished( | |||||||
|     SSL_DEBUG_MSG( 2, ( "<= calc  finished" ) ); |     SSL_DEBUG_MSG( 2, ( "<= calc  finished" ) ); | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| int ssl_write_finished( ssl_context *ssl ) | static void ssl_calc_finished_tls( | ||||||
|  |                 ssl_context *ssl, unsigned char *buf, int from ) | ||||||
| { | { | ||||||
|     int ret, hash_len; |     int len = 12; | ||||||
|      md5_context  md5; |     char *sender; | ||||||
|  |     md5_context  md5; | ||||||
|     sha1_context sha1; |     sha1_context sha1; | ||||||
|  |     unsigned char padbuf[36]; | ||||||
| 
 | 
 | ||||||
|     SSL_DEBUG_MSG( 2, ( "=> write finished" ) ); |     SSL_DEBUG_MSG( 2, ( "=> calc  finished tls" ) ); | ||||||
| 
 | 
 | ||||||
|     memcpy( &md5 , &ssl->fin_md5 , sizeof(  md5_context ) ); |     memcpy( &md5 , &ssl->fin_md5 , sizeof(  md5_context ) ); | ||||||
|     memcpy( &sha1, &ssl->fin_sha1, sizeof( sha1_context ) ); |     memcpy( &sha1, &ssl->fin_sha1, sizeof( sha1_context ) ); | ||||||
| 
 | 
 | ||||||
|     ssl_calc_finished( ssl, ssl->out_msg + 4, |     /*
 | ||||||
|                        ssl->endpoint, &md5, &sha1 ); |      * TLSv1: | ||||||
|  |      *   hash = PRF( master, finished_label, | ||||||
|  |      *               MD5( handshake ) + SHA1( handshake ) )[0..11] | ||||||
|  |      */ | ||||||
| 
 | 
 | ||||||
|  |     SSL_DEBUG_BUF( 4, "finished  md5 state", (unsigned char *) | ||||||
|  |                     md5.state, sizeof(  md5.state ) ); | ||||||
|  | 
 | ||||||
|  |     SSL_DEBUG_BUF( 4, "finished sha1 state", (unsigned char *) | ||||||
|  |                    sha1.state, sizeof( sha1.state ) ); | ||||||
|  | 
 | ||||||
|  |     sender = ( from == SSL_IS_CLIENT ) | ||||||
|  |              ? (char *) "client finished" | ||||||
|  |              : (char *) "server finished"; | ||||||
|  | 
 | ||||||
|  |     md5_finish(  &md5, padbuf ); | ||||||
|  |     sha1_finish( &sha1, padbuf + 16 ); | ||||||
|  | 
 | ||||||
|  |     ssl->tls_prf( ssl->session->master, 48, sender, | ||||||
|  |             padbuf, 36, buf, len ); | ||||||
|  | 
 | ||||||
|  |     SSL_DEBUG_BUF( 3, "calc finished result", buf, len ); | ||||||
|  | 
 | ||||||
|  |     memset(  &md5, 0, sizeof(  md5_context ) ); | ||||||
|  |     memset( &sha1, 0, sizeof( sha1_context ) ); | ||||||
|  | 
 | ||||||
|  |     memset(  padbuf, 0, sizeof(  padbuf ) ); | ||||||
|  | 
 | ||||||
|  |     SSL_DEBUG_MSG( 2, ( "<= calc  finished" ) ); | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | static void ssl_calc_finished_tls1_2( | ||||||
|  |                 ssl_context *ssl, unsigned char *buf, int from ) | ||||||
|  | { | ||||||
|  |     int len = 12; | ||||||
|  |     char *sender; | ||||||
|  |     sha2_context sha2; | ||||||
|  |     unsigned char padbuf[32]; | ||||||
|  | 
 | ||||||
|  |     SSL_DEBUG_MSG( 2, ( "=> calc  finished tls 1.2" ) ); | ||||||
|  | 
 | ||||||
|  |     memcpy( &sha2, &ssl->fin_sha2, sizeof( sha2_context ) ); | ||||||
|  | 
 | ||||||
|  |     /*
 | ||||||
|  |      * TLSv1.2: | ||||||
|  |      *   hash = PRF( master, finished_label, | ||||||
|  |      *               Hash( handshake ) )[0.11] | ||||||
|  |      */ | ||||||
|  | 
 | ||||||
|  |     SSL_DEBUG_BUF( 4, "finished sha2 state", (unsigned char *) | ||||||
|  |                    sha2.state, sizeof( sha2.state ) ); | ||||||
|  | 
 | ||||||
|  |     sender = ( from == SSL_IS_CLIENT ) | ||||||
|  |              ? (char *) "client finished" | ||||||
|  |              : (char *) "server finished"; | ||||||
|  | 
 | ||||||
|  |     sha2_finish( &sha2, padbuf ); | ||||||
|  | 
 | ||||||
|  |     ssl->tls_prf( ssl->session->master, 48, sender, | ||||||
|  |                   padbuf, 32, buf, len ); | ||||||
|  | 
 | ||||||
|  |     SSL_DEBUG_BUF( 3, "calc finished result", buf, len ); | ||||||
|  | 
 | ||||||
|  |     memset( &sha2, 0, sizeof( sha2_context ) ); | ||||||
|  | 
 | ||||||
|  |     memset(  padbuf, 0, sizeof(  padbuf ) ); | ||||||
|  | 
 | ||||||
|  |     SSL_DEBUG_MSG( 2, ( "<= calc  finished" ) ); | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | int ssl_write_finished( ssl_context *ssl ) | ||||||
|  | { | ||||||
|  |     int ret, hash_len; | ||||||
|  | 
 | ||||||
|  |     SSL_DEBUG_MSG( 2, ( "=> write finished" ) ); | ||||||
|  | 
 | ||||||
|  |     ssl->calc_finished( ssl, ssl->out_msg + 4, ssl->endpoint ); | ||||||
|  | 
 | ||||||
|  |     // TODO TLS/1.2 Hash length is determined by cipher suite (Page 63)
 | ||||||
|     hash_len = ( ssl->minor_ver == SSL_MINOR_VERSION_0 ) ? 36 : 12; |     hash_len = ( ssl->minor_ver == SSL_MINOR_VERSION_0 ) ? 36 : 12; | ||||||
| 
 | 
 | ||||||
|     ssl->out_msglen  = 4 + hash_len; |     ssl->out_msglen  = 4 + hash_len; | ||||||
| @ -1741,13 +1874,10 @@ int ssl_parse_finished( ssl_context *ssl ) | |||||||
|     int ret; |     int ret; | ||||||
|     unsigned int hash_len; |     unsigned int hash_len; | ||||||
|     unsigned char buf[36]; |     unsigned char buf[36]; | ||||||
|     md5_context  md5; |  | ||||||
|     sha1_context sha1; |  | ||||||
| 
 | 
 | ||||||
|     SSL_DEBUG_MSG( 2, ( "=> parse finished" ) ); |     SSL_DEBUG_MSG( 2, ( "=> parse finished" ) ); | ||||||
| 
 | 
 | ||||||
|     memcpy( &md5 , &ssl->fin_md5 , sizeof(  md5_context ) ); |     ssl->calc_finished( ssl, buf, ssl->endpoint ^ 1 ); | ||||||
|     memcpy( &sha1, &ssl->fin_sha1, sizeof( sha1_context ) ); |  | ||||||
| 
 | 
 | ||||||
|     ssl->do_crypt = 1; |     ssl->do_crypt = 1; | ||||||
| 
 | 
 | ||||||
| @ -1763,6 +1893,7 @@ int ssl_parse_finished( ssl_context *ssl ) | |||||||
|         return( POLARSSL_ERR_SSL_UNEXPECTED_MESSAGE ); |         return( POLARSSL_ERR_SSL_UNEXPECTED_MESSAGE ); | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|  |     // TODO TLS/1.2 Hash length is determined by cipher suite (Page 63)
 | ||||||
|     hash_len = ( ssl->minor_ver == SSL_MINOR_VERSION_0 ) ? 36 : 12; |     hash_len = ( ssl->minor_ver == SSL_MINOR_VERSION_0 ) ? 36 : 12; | ||||||
| 
 | 
 | ||||||
|     if( ssl->in_msg[0] != SSL_HS_FINISHED || |     if( ssl->in_msg[0] != SSL_HS_FINISHED || | ||||||
| @ -1772,8 +1903,6 @@ int ssl_parse_finished( ssl_context *ssl ) | |||||||
|         return( POLARSSL_ERR_SSL_BAD_HS_FINISHED ); |         return( POLARSSL_ERR_SSL_BAD_HS_FINISHED ); | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|     ssl_calc_finished( ssl, buf, ssl->endpoint ^ 1, &md5, &sha1 ); |  | ||||||
| 
 |  | ||||||
|     if( memcmp( ssl->in_msg + 4, buf, hash_len ) != 0 ) |     if( memcmp( ssl->in_msg + 4, buf, hash_len ) != 0 ) | ||||||
|     { |     { | ||||||
|         SSL_DEBUG_MSG( 1, ( "bad finished message" ) ); |         SSL_DEBUG_MSG( 1, ( "bad finished message" ) ); | ||||||
| @ -1834,6 +1963,7 @@ int ssl_init( ssl_context *ssl ) | |||||||
| 
 | 
 | ||||||
|      md5_starts( &ssl->fin_md5  ); |      md5_starts( &ssl->fin_md5  ); | ||||||
|     sha1_starts( &ssl->fin_sha1 ); |     sha1_starts( &ssl->fin_sha1 ); | ||||||
|  |     sha2_starts( &ssl->fin_sha2, 0 ); | ||||||
| 
 | 
 | ||||||
|     return( 0 ); |     return( 0 ); | ||||||
| } | } | ||||||
| @ -1879,6 +2009,7 @@ void ssl_session_reset( ssl_context *ssl ) | |||||||
| 
 | 
 | ||||||
|      md5_starts( &ssl->fin_md5  ); |      md5_starts( &ssl->fin_md5  ); | ||||||
|     sha1_starts( &ssl->fin_sha1 ); |     sha1_starts( &ssl->fin_sha1 ); | ||||||
|  |     sha2_starts( &ssl->fin_sha2, 0 ); | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| /*
 | /*
 | ||||||
| @ -2199,6 +2330,9 @@ const char *ssl_get_version( const ssl_context *ssl ) | |||||||
|         case SSL_MINOR_VERSION_2: |         case SSL_MINOR_VERSION_2: | ||||||
|             return( "TLSv1.1" ); |             return( "TLSv1.1" ); | ||||||
| 
 | 
 | ||||||
|  |         case SSL_MINOR_VERSION_3: | ||||||
|  |             return( "TLSv1.2" ); | ||||||
|  | 
 | ||||||
|         default: |         default: | ||||||
|             break; |             break; | ||||||
|     } |     } | ||||||
|  | |||||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user
	 Paul Bakker
						Paul Bakker