@ -56,6 +56,7 @@
# include <openssl/rsa.h>
# include <openssl/rsa.h>
# include <assert.h>
# include <limits.h>
# include <limits.h>
# include <string.h>
# include <string.h>
@ -470,18 +471,43 @@ static const struct pkcs1_sig_prefix kPKCS1SigPrefixes[] = {
} ,
} ,
} ;
} ;
int RSA_add_pkcs1_prefix ( uint8_t * * out_msg , size_t * out_msg_len ,
static int rsa_check_digest_size ( int hash_nid , size_t digest_len ) {
int * is_alloced , int hash_nid , const uint8_t * digest ,
size_t digest_len ) {
if ( hash_nid = = NID_md5_sha1 ) {
if ( hash_nid = = NID_md5_sha1 ) {
// Special case: SSL signature, just check the length.
if ( digest_len ! = SSL_SIG_LENGTH ) {
if ( digest_len ! = SSL_SIG_LENGTH ) {
OPENSSL_PUT_ERROR ( RSA , RSA_R_INVALID_MESSAGE_LENGTH ) ;
OPENSSL_PUT_ERROR ( RSA , RSA_R_INVALID_MESSAGE_LENGTH ) ;
return 0 ;
return 0 ;
}
}
return 1 ;
}
for ( size_t i = 0 ; kPKCS1SigPrefixes [ i ] . nid ! = NID_undef ; i + + ) {
const struct pkcs1_sig_prefix * sig_prefix = & kPKCS1SigPrefixes [ i ] ;
if ( sig_prefix - > nid = = hash_nid ) {
if ( digest_len ! = sig_prefix - > hash_len ) {
OPENSSL_PUT_ERROR ( RSA , RSA_R_INVALID_MESSAGE_LENGTH ) ;
return 0 ;
}
return 1 ;
}
}
OPENSSL_PUT_ERROR ( RSA , RSA_R_UNKNOWN_ALGORITHM_TYPE ) ;
return 0 ;
}
int RSA_add_pkcs1_prefix ( uint8_t * * out_msg , size_t * out_msg_len ,
int * is_alloced , int hash_nid , const uint8_t * digest ,
size_t digest_len ) {
if ( ! rsa_check_digest_size ( hash_nid , digest_len ) ) {
return 0 ;
}
if ( hash_nid = = NID_md5_sha1 ) {
// The length should already have been checked.
assert ( digest_len = = SSL_SIG_LENGTH ) ;
* out_msg = ( uint8_t * ) digest ;
* out_msg = ( uint8_t * ) digest ;
* out_msg_len = SSL_SIG_LENGTH ;
* out_msg_len = digest_len ;
* is_alloced = 0 ;
* is_alloced = 0 ;
return 1 ;
return 1 ;
}
}
@ -492,11 +518,8 @@ int RSA_add_pkcs1_prefix(uint8_t **out_msg, size_t *out_msg_len,
continue ;
continue ;
}
}
if ( digest_len ! = sig_prefix - > hash_len ) {
// The length should already have been checked.
OPENSSL_PUT_ERROR ( RSA , RSA_R_INVALID_MESSAGE_LENGTH ) ;
assert ( digest_len = = sig_prefix - > hash_len ) ;
return 0 ;
}
const uint8_t * prefix = sig_prefix - > bytes ;
const uint8_t * prefix = sig_prefix - > bytes ;
size_t prefix_len = sig_prefix - > len ;
size_t prefix_len = sig_prefix - > len ;
size_t signed_msg_len = prefix_len + digest_len ;
size_t signed_msg_len = prefix_len + digest_len ;
@ -526,19 +549,25 @@ int RSA_add_pkcs1_prefix(uint8_t **out_msg, size_t *out_msg_len,
}
}
int rsa_sign_no_self_test ( int hash_nid , const uint8_t * digest ,
int rsa_sign_no_self_test ( int hash_nid , const uint8_t * digest ,
unsigned digest_len , uint8_t * out , unsigned * out_len ,
size_t digest_len , uint8_t * out , unsigned * out_len ,
RSA * rsa ) {
RSA * rsa ) {
if ( rsa - > meth - > sign ) {
if ( ! rsa_check_digest_size ( hash_nid , digest_len ) ) {
return 0 ;
}
// All supported digest lengths fit in |unsigned|.
assert ( digest_len < = EVP_MAX_MD_SIZE ) ;
static_assert ( EVP_MAX_MD_SIZE < = UINT_MAX , " digest too long " ) ;
return rsa - > meth - > sign ( hash_nid , digest , ( unsigned ) digest_len , out , out_len ,
rsa ) ;
}
const unsigned rsa_size = RSA_size ( rsa ) ;
const unsigned rsa_size = RSA_size ( rsa ) ;
int ret = 0 ;
int ret = 0 ;
uint8_t * signed_msg = NULL ;
uint8_t * signed_msg = NULL ;
size_t signed_msg_len = 0 ;
size_t signed_msg_len = 0 ;
int signed_msg_is_alloced = 0 ;
int signed_msg_is_alloced = 0 ;
size_t size_t_out_len ;
size_t size_t_out_len ;
if ( rsa - > meth - > sign ) {
return rsa - > meth - > sign ( hash_nid , digest , digest_len , out , out_len , rsa ) ;
}
if ( ! RSA_add_pkcs1_prefix ( & signed_msg , & signed_msg_len ,
if ( ! RSA_add_pkcs1_prefix ( & signed_msg , & signed_msg_len ,
& signed_msg_is_alloced , hash_nid , digest ,
& signed_msg_is_alloced , hash_nid , digest ,
digest_len ) | |
digest_len ) | |
@ -563,7 +592,7 @@ err:
return ret ;
return ret ;
}
}
int RSA_sign ( int hash_nid , const uint8_t * digest , unsigned digest_len ,
int RSA_sign ( int hash_nid , const uint8_t * digest , size_t digest_len ,
uint8_t * out , unsigned * out_len , RSA * rsa ) {
uint8_t * out , unsigned * out_len , RSA * rsa ) {
boringssl_ensure_rsa_self_test ( ) ;
boringssl_ensure_rsa_self_test ( ) ;