mirror of
				https://github.com/cuberite/polarssl.git
				synced 2025-11-03 20:22:59 -05:00 
			
		
		
		
	- RSASSA-PSS verification now properly handles salt lengths other than hlen
This commit is contained in:
		
							parent
							
								
									fbc4a45f15
								
							
						
					
					
						commit
						53019ae6f7
					
				@ -580,7 +580,7 @@ int rsa_pkcs1_sign( rsa_context *ctx,
 | 
				
			|||||||
    unsigned char salt[POLARSSL_MD_MAX_SIZE];
 | 
					    unsigned char salt[POLARSSL_MD_MAX_SIZE];
 | 
				
			||||||
    const md_info_t *md_info;
 | 
					    const md_info_t *md_info;
 | 
				
			||||||
    md_context_t md_ctx;
 | 
					    md_context_t md_ctx;
 | 
				
			||||||
    int i, hlen, msb, offset = 0;
 | 
					    int i, slen, hlen, msb, offset = 0;
 | 
				
			||||||
#else
 | 
					#else
 | 
				
			||||||
    (void) f_rng;
 | 
					    (void) f_rng;
 | 
				
			||||||
    (void) p_rng;
 | 
					    (void) p_rng;
 | 
				
			||||||
@ -733,6 +733,8 @@ int rsa_pkcs1_sign( rsa_context *ctx,
 | 
				
			|||||||
                return( POLARSSL_ERR_RSA_BAD_INPUT_DATA );
 | 
					                return( POLARSSL_ERR_RSA_BAD_INPUT_DATA );
 | 
				
			||||||
                
 | 
					                
 | 
				
			||||||
            hlen = md_get_size( md_info );
 | 
					            hlen = md_get_size( md_info );
 | 
				
			||||||
 | 
					            slen = hlen;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
            memset( sig, 0, olen );
 | 
					            memset( sig, 0, olen );
 | 
				
			||||||
            memset( &md_ctx, 0, sizeof( md_context_t ) );
 | 
					            memset( &md_ctx, 0, sizeof( md_context_t ) );
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@ -740,9 +742,9 @@ int rsa_pkcs1_sign( rsa_context *ctx,
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
            msb = mpi_msb( &ctx->N ) - 1;
 | 
					            msb = mpi_msb( &ctx->N ) - 1;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
            // Generate salt of length hlen
 | 
					            // Generate salt of length slen
 | 
				
			||||||
            //
 | 
					            //
 | 
				
			||||||
            for( i = 0; i < hlen; ++i )
 | 
					            for( i = 0; i < slen; ++i )
 | 
				
			||||||
                salt[i] = (unsigned char) f_rng( p_rng ); 
 | 
					                salt[i] = (unsigned char) f_rng( p_rng ); 
 | 
				
			||||||
 | 
					
 | 
				
			||||||
            // Note: EMSA-PSS encoding is over the length of N - 1 bits
 | 
					            // Note: EMSA-PSS encoding is over the length of N - 1 bits
 | 
				
			||||||
@ -750,15 +752,15 @@ int rsa_pkcs1_sign( rsa_context *ctx,
 | 
				
			|||||||
            msb = mpi_msb( &ctx->N ) - 1;
 | 
					            msb = mpi_msb( &ctx->N ) - 1;
 | 
				
			||||||
            p += olen - hlen * 2 - 2;
 | 
					            p += olen - hlen * 2 - 2;
 | 
				
			||||||
            *p++ = 0x01;
 | 
					            *p++ = 0x01;
 | 
				
			||||||
            memcpy( p, salt, hlen );
 | 
					            memcpy( p, salt, slen );
 | 
				
			||||||
            p += hlen;
 | 
					            p += slen;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
            // Generate H = Hash( M' )
 | 
					            // Generate H = Hash( M' )
 | 
				
			||||||
            //
 | 
					            //
 | 
				
			||||||
            md_starts( &md_ctx );
 | 
					            md_starts( &md_ctx );
 | 
				
			||||||
            md_update( &md_ctx, p, 8 );
 | 
					            md_update( &md_ctx, p, 8 );
 | 
				
			||||||
            md_update( &md_ctx, hash, hashlen );
 | 
					            md_update( &md_ctx, hash, hashlen );
 | 
				
			||||||
            md_update( &md_ctx, salt, hlen );
 | 
					            md_update( &md_ctx, salt, slen );
 | 
				
			||||||
            md_finish( &md_ctx, p );
 | 
					            md_finish( &md_ctx, p );
 | 
				
			||||||
 | 
					
 | 
				
			||||||
            // Compensate for boundary condition when applying mask
 | 
					            // Compensate for boundary condition when applying mask
 | 
				
			||||||
@ -805,7 +807,7 @@ int rsa_pkcs1_verify( rsa_context *ctx,
 | 
				
			|||||||
    unsigned char zeros[8];
 | 
					    unsigned char zeros[8];
 | 
				
			||||||
    const md_info_t *md_info;
 | 
					    const md_info_t *md_info;
 | 
				
			||||||
    md_context_t md_ctx;
 | 
					    md_context_t md_ctx;
 | 
				
			||||||
    int hlen, msb;
 | 
					    int slen, hlen, msb;
 | 
				
			||||||
#endif
 | 
					#endif
 | 
				
			||||||
    siglen = ctx->len;
 | 
					    siglen = ctx->len;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@ -935,6 +937,8 @@ int rsa_pkcs1_verify( rsa_context *ctx,
 | 
				
			|||||||
                return( POLARSSL_ERR_RSA_BAD_INPUT_DATA );
 | 
					                return( POLARSSL_ERR_RSA_BAD_INPUT_DATA );
 | 
				
			||||||
                
 | 
					                
 | 
				
			||||||
            hlen = md_get_size( md_info );
 | 
					            hlen = md_get_size( md_info );
 | 
				
			||||||
 | 
					            slen = siglen - hlen - 1;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
            memset( &md_ctx, 0, sizeof( md_context_t ) );
 | 
					            memset( &md_ctx, 0, sizeof( md_context_t ) );
 | 
				
			||||||
            memset( zeros, 0, 8 );
 | 
					            memset( zeros, 0, 8 );
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@ -967,15 +971,17 @@ int rsa_pkcs1_verify( rsa_context *ctx,
 | 
				
			|||||||
            if( *p++ != 0x01 )
 | 
					            if( *p++ != 0x01 )
 | 
				
			||||||
                return( POLARSSL_ERR_RSA_INVALID_PADDING );
 | 
					                return( POLARSSL_ERR_RSA_INVALID_PADDING );
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            slen -= p - buf;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
            // Generate H = Hash( M' )
 | 
					            // Generate H = Hash( M' )
 | 
				
			||||||
            //
 | 
					            //
 | 
				
			||||||
            md_starts( &md_ctx );
 | 
					            md_starts( &md_ctx );
 | 
				
			||||||
            md_update( &md_ctx, zeros, 8 );
 | 
					            md_update( &md_ctx, zeros, 8 );
 | 
				
			||||||
            md_update( &md_ctx, hash, hashlen );
 | 
					            md_update( &md_ctx, hash, hashlen );
 | 
				
			||||||
            md_update( &md_ctx, p, hlen );
 | 
					            md_update( &md_ctx, p, slen );
 | 
				
			||||||
            md_finish( &md_ctx, p );
 | 
					            md_finish( &md_ctx, p );
 | 
				
			||||||
 | 
					
 | 
				
			||||||
            if( memcmp( p, p + hlen, hlen ) == 0 )
 | 
					            if( memcmp( p, p + slen, hlen ) == 0 )
 | 
				
			||||||
                return( 0 );
 | 
					                return( 0 );
 | 
				
			||||||
            else
 | 
					            else
 | 
				
			||||||
                return( POLARSSL_ERR_RSA_VERIFY_FAILED );
 | 
					                return( POLARSSL_ERR_RSA_VERIFY_FAILED );
 | 
				
			||||||
 | 
				
			|||||||
@ -1827,8 +1827,6 @@ int x509parse_key( rsa_context *rsa, const unsigned char *key, int keylen,
 | 
				
			|||||||
#endif
 | 
					#endif
 | 
				
			||||||
    end = p + keylen;
 | 
					    end = p + keylen;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    memset( rsa, 0, sizeof( rsa_context ) );
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    /*
 | 
					    /*
 | 
				
			||||||
     *  RSAPrivateKey ::= SEQUENCE {
 | 
					     *  RSAPrivateKey ::= SEQUENCE {
 | 
				
			||||||
     *      version           Version,
 | 
					     *      version           Version,
 | 
				
			||||||
@ -1941,6 +1939,116 @@ int x509parse_keyfile( rsa_context *rsa, const char *path, const char *pwd )
 | 
				
			|||||||
    return( ret );
 | 
					    return( ret );
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/*
 | 
				
			||||||
 | 
					 * Parse a public RSA key
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
 | 
					int x509parse_public_key( rsa_context *rsa, const unsigned char *key, int keylen )
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					    int ret, len;
 | 
				
			||||||
 | 
					    unsigned char *p, *end;
 | 
				
			||||||
 | 
					    x509_buf alg_oid;
 | 
				
			||||||
 | 
					#if defined(POLARSSL_PEM_C)
 | 
				
			||||||
 | 
					    pem_context pem;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    pem_init( &pem );
 | 
				
			||||||
 | 
					    ret = pem_read_buffer( &pem,
 | 
				
			||||||
 | 
					            "-----BEGIN PUBLIC KEY-----",
 | 
				
			||||||
 | 
					            "-----END PUBLIC KEY-----",
 | 
				
			||||||
 | 
					            key, NULL, 0, &len );
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    if( ret == 0 )
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					        /*
 | 
				
			||||||
 | 
					         * Was PEM encoded
 | 
				
			||||||
 | 
					         */
 | 
				
			||||||
 | 
					        keylen = pem.buflen;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					    else if( ret != POLARSSL_ERR_PEM_NO_HEADER_PRESENT )
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					        pem_free( &pem );
 | 
				
			||||||
 | 
					        return( ret );
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    p = ( ret == 0 ) ? pem.buf : (unsigned char *) key;
 | 
				
			||||||
 | 
					#else
 | 
				
			||||||
 | 
					    p = (unsigned char *) key;
 | 
				
			||||||
 | 
					#endif
 | 
				
			||||||
 | 
					    end = p + keylen;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    /*
 | 
				
			||||||
 | 
					     *  PublicKeyInfo ::= SEQUENCE {
 | 
				
			||||||
 | 
					     *    algorithm       AlgorithmIdentifier,
 | 
				
			||||||
 | 
					     *    PublicKey       BIT STRING
 | 
				
			||||||
 | 
					     *  }
 | 
				
			||||||
 | 
					     *
 | 
				
			||||||
 | 
					     *  AlgorithmIdentifier ::= SEQUENCE {
 | 
				
			||||||
 | 
					     *    algorithm       OBJECT IDENTIFIER,
 | 
				
			||||||
 | 
					     *    parameters      ANY DEFINED BY algorithm OPTIONAL
 | 
				
			||||||
 | 
					     *  }
 | 
				
			||||||
 | 
					     *
 | 
				
			||||||
 | 
					     *  RSAPublicKey ::= SEQUENCE {
 | 
				
			||||||
 | 
					     *      modulus           INTEGER,  -- n
 | 
				
			||||||
 | 
					     *      publicExponent    INTEGER   -- e
 | 
				
			||||||
 | 
					     *  }
 | 
				
			||||||
 | 
					     */
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    if( ( ret = asn1_get_tag( &p, end, &len,
 | 
				
			||||||
 | 
					                    ASN1_CONSTRUCTED | ASN1_SEQUENCE ) ) != 0 )
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					#if defined(POLARSSL_PEM_C)
 | 
				
			||||||
 | 
					        pem_free( &pem );
 | 
				
			||||||
 | 
					#endif
 | 
				
			||||||
 | 
					        rsa_free( rsa );
 | 
				
			||||||
 | 
					        return( POLARSSL_ERR_X509_CERT_INVALID_FORMAT | ret );
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    if( ( ret = x509_get_pubkey( &p, end, &alg_oid, &rsa->N, &rsa->E ) ) != 0 )
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					#if defined(POLARSSL_PEM_C)
 | 
				
			||||||
 | 
					        pem_free( &pem );
 | 
				
			||||||
 | 
					#endif
 | 
				
			||||||
 | 
					        rsa_free( rsa );
 | 
				
			||||||
 | 
					        return( POLARSSL_ERR_X509_KEY_INVALID_FORMAT | ret );
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    if( ( ret = rsa_check_pubkey( rsa ) ) != 0 )
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					#if defined(POLARSSL_PEM_C)
 | 
				
			||||||
 | 
					        pem_free( &pem );
 | 
				
			||||||
 | 
					#endif
 | 
				
			||||||
 | 
					        rsa_free( rsa );
 | 
				
			||||||
 | 
					        return( ret );
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    rsa->len = mpi_size( &rsa->N );
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#if defined(POLARSSL_PEM_C)
 | 
				
			||||||
 | 
					    pem_free( &pem );
 | 
				
			||||||
 | 
					#endif
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    return( 0 );
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/*
 | 
				
			||||||
 | 
					 * Load and parse a public RSA key
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
 | 
					int x509parse_public_keyfile( rsa_context *rsa, const char *path )
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					    int ret;
 | 
				
			||||||
 | 
					    size_t n;
 | 
				
			||||||
 | 
					    unsigned char *buf;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    if ( load_file( path, &buf, &n ) )
 | 
				
			||||||
 | 
					        return( 1 );
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    ret = x509parse_public_key( rsa, buf, (int) n );
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    memset( buf, 0, n + 1 );
 | 
				
			||||||
 | 
					    free( buf );
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    return( ret );
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
/*
 | 
					/*
 | 
				
			||||||
 * Parse DHM parameters
 | 
					 * Parse DHM parameters
 | 
				
			||||||
 */
 | 
					 */
 | 
				
			||||||
 | 
				
			|||||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user