mirror of
https://github.com/ipxe/ipxe
synced 2025-12-07 01:40:28 +03:00
[crypto] Pass signatures for verification as ASN.1 cursors
Signed-off-by: Michael Brown <mcb30@ipxe.org>
This commit is contained in:
@@ -757,7 +757,7 @@ static int cms_verify_digest ( struct cms_message *cms,
|
||||
|
||||
/* Verify digest */
|
||||
if ( ( rc = pubkey_verify ( pubkey, key, digest, digest_out,
|
||||
value->data, value->len ) ) != 0 ) {
|
||||
value ) ) != 0 ) {
|
||||
DBGC ( cms, "CMS %p/%p signature verification failed: %s\n",
|
||||
cms, part, strerror ( rc ) );
|
||||
return rc;
|
||||
|
||||
@@ -120,8 +120,7 @@ int pubkey_null_sign ( const struct asn1_cursor *key __unused,
|
||||
int pubkey_null_verify ( const struct asn1_cursor *key __unused,
|
||||
struct digest_algorithm *digest __unused,
|
||||
const void *value __unused,
|
||||
const void *signature __unused ,
|
||||
size_t signature_len __unused ) {
|
||||
const struct asn1_cursor *signature __unused ) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
@@ -858,8 +858,7 @@ static int ocsp_check_signature ( struct ocsp_check *ocsp,
|
||||
|
||||
/* Verify digest */
|
||||
if ( ( rc = pubkey_verify ( pubkey, key, digest, digest_out,
|
||||
response->signature.data,
|
||||
response->signature.len ) ) != 0 ) {
|
||||
&response->signature ) ) != 0 ) {
|
||||
DBGC ( ocsp, "OCSP %p \"%s\" signature verification failed: "
|
||||
"%s\n", ocsp, x509_name ( ocsp->cert ), strerror ( rc ));
|
||||
return rc;
|
||||
|
||||
@@ -591,12 +591,11 @@ static int rsa_sign ( const struct asn1_cursor *key,
|
||||
* @v digest Digest algorithm
|
||||
* @v value Digest value
|
||||
* @v signature Signature
|
||||
* @v signature_len Signature length
|
||||
* @ret rc Return status code
|
||||
*/
|
||||
static int rsa_verify ( const struct asn1_cursor *key,
|
||||
struct digest_algorithm *digest, const void *value,
|
||||
const void *signature, size_t signature_len ) {
|
||||
const struct asn1_cursor *signature ) {
|
||||
struct rsa_context context;
|
||||
void *temp;
|
||||
void *expected;
|
||||
@@ -606,17 +605,17 @@ static int rsa_verify ( const struct asn1_cursor *key,
|
||||
DBGC ( &context, "RSA %p verifying %s digest:\n",
|
||||
&context, digest->name );
|
||||
DBGC_HDA ( &context, 0, value, digest->digestsize );
|
||||
DBGC_HDA ( &context, 0, signature, signature_len );
|
||||
DBGC_HDA ( &context, 0, signature->data, signature->len );
|
||||
|
||||
/* Initialise context */
|
||||
if ( ( rc = rsa_init ( &context, key ) ) != 0 )
|
||||
goto err_init;
|
||||
|
||||
/* Sanity check */
|
||||
if ( signature_len != context.max_len ) {
|
||||
if ( signature->len != context.max_len ) {
|
||||
DBGC ( &context, "RSA %p signature incorrect length (%zd "
|
||||
"bytes, should be %zd)\n",
|
||||
&context, signature_len, context.max_len );
|
||||
&context, signature->len, context.max_len );
|
||||
rc = -ERANGE;
|
||||
goto err_sanity;
|
||||
}
|
||||
@@ -626,7 +625,7 @@ static int rsa_verify ( const struct asn1_cursor *key,
|
||||
*/
|
||||
temp = context.input0;
|
||||
expected = temp;
|
||||
rsa_cipher ( &context, signature, expected );
|
||||
rsa_cipher ( &context, signature->data, expected );
|
||||
DBGC ( &context, "RSA %p deciphered signature:\n", &context );
|
||||
DBGC_HDA ( &context, 0, expected, context.max_len );
|
||||
|
||||
|
||||
@@ -1152,8 +1152,7 @@ static int x509_check_signature ( struct x509_certificate *cert,
|
||||
|
||||
/* Verify signature using signer's public key */
|
||||
if ( ( rc = pubkey_verify ( pubkey, &public_key->raw, digest,
|
||||
digest_out, signature->value.data,
|
||||
signature->value.len ) ) != 0 ) {
|
||||
digest_out, &signature->value ) ) != 0 ) {
|
||||
DBGC ( cert, "X509 %p \"%s\" signature verification failed: "
|
||||
"%s\n", cert, x509_name ( cert ), strerror ( rc ) );
|
||||
goto err_pubkey_verify;
|
||||
|
||||
@@ -164,12 +164,11 @@ struct pubkey_algorithm {
|
||||
* @v digest Digest algorithm
|
||||
* @v value Digest value
|
||||
* @v signature Signature
|
||||
* @v signature_len Signature length
|
||||
* @ret rc Return status code
|
||||
*/
|
||||
int ( * verify ) ( const struct asn1_cursor *key,
|
||||
struct digest_algorithm *digest, const void *value,
|
||||
const void *signature, size_t signature_len );
|
||||
const struct asn1_cursor *signature );
|
||||
/** Check that public key matches private key
|
||||
*
|
||||
* @v private_key Private key
|
||||
@@ -295,8 +294,8 @@ pubkey_sign ( struct pubkey_algorithm *pubkey, const struct asn1_cursor *key,
|
||||
static inline __attribute__ (( always_inline )) int
|
||||
pubkey_verify ( struct pubkey_algorithm *pubkey, const struct asn1_cursor *key,
|
||||
struct digest_algorithm *digest, const void *value,
|
||||
const void *signature, size_t signature_len ) {
|
||||
return pubkey->verify ( key, digest, value, signature, signature_len );
|
||||
const struct asn1_cursor *signature ) {
|
||||
return pubkey->verify ( key, digest, value, signature );
|
||||
}
|
||||
|
||||
static inline __attribute__ (( always_inline )) int
|
||||
@@ -336,8 +335,8 @@ extern int pubkey_null_sign ( const struct asn1_cursor *key,
|
||||
const void *value, void *signature );
|
||||
extern int pubkey_null_verify ( const struct asn1_cursor *key,
|
||||
struct digest_algorithm *digest,
|
||||
const void *value, const void *signature ,
|
||||
size_t signature_len );
|
||||
const void *value,
|
||||
const struct asn1_cursor *signature );
|
||||
|
||||
extern struct digest_algorithm digest_null;
|
||||
extern struct cipher_algorithm cipher_null;
|
||||
|
||||
@@ -1495,6 +1495,7 @@ static int tls_verify_dh_params ( struct tls_connection *tls,
|
||||
uint16_t signature_len;
|
||||
uint8_t signature[0];
|
||||
} __attribute__ (( packed )) *sig;
|
||||
struct asn1_cursor signature;
|
||||
const void *data;
|
||||
size_t remaining;
|
||||
int rc;
|
||||
@@ -1515,6 +1516,8 @@ static int tls_verify_dh_params ( struct tls_connection *tls,
|
||||
tls->server.exchange_len );
|
||||
return -EINVAL_KEY_EXCHANGE;
|
||||
}
|
||||
signature.data = sig->signature;
|
||||
signature.len = ntohs ( sig->signature_len );
|
||||
|
||||
/* Identify signature and hash algorithm */
|
||||
if ( use_sig_hash ) {
|
||||
@@ -1538,8 +1541,6 @@ static int tls_verify_dh_params ( struct tls_connection *tls,
|
||||
|
||||
/* Verify signature */
|
||||
{
|
||||
const void *signature = sig->signature;
|
||||
size_t signature_len = ntohs ( sig->signature_len );
|
||||
uint8_t ctx[digest->ctxsize];
|
||||
uint8_t hash[digest->digestsize];
|
||||
|
||||
@@ -1553,9 +1554,8 @@ static int tls_verify_dh_params ( struct tls_connection *tls,
|
||||
digest_final ( digest, ctx, hash );
|
||||
|
||||
/* Verify signature */
|
||||
if ( ( rc = pubkey_verify ( pubkey, &tls->server.key,
|
||||
digest, hash, signature,
|
||||
signature_len ) ) != 0 ) {
|
||||
if ( ( rc = pubkey_verify ( pubkey, &tls->server.key, digest,
|
||||
hash, &signature ) ) != 0 ) {
|
||||
DBGC ( tls, "TLS %p ServerKeyExchange failed "
|
||||
"verification\n", tls );
|
||||
DBGC_HDA ( tls, 0, tls->server.exchange,
|
||||
|
||||
@@ -99,10 +99,11 @@ void pubkey_sign_okx ( struct pubkey_sign_test *test, const char *file,
|
||||
struct pubkey_algorithm *pubkey = test->pubkey;
|
||||
struct digest_algorithm *digest = test->digest;
|
||||
size_t max_len = pubkey_max_len ( pubkey, &test->private );
|
||||
uint8_t bad[test->signature_len];
|
||||
uint8_t bad[test->signature.len];
|
||||
uint8_t digestctx[digest->ctxsize ];
|
||||
uint8_t digestout[digest->digestsize];
|
||||
uint8_t signature[max_len];
|
||||
struct asn1_cursor cursor;
|
||||
int signature_len;
|
||||
|
||||
/* Construct digest over plaintext */
|
||||
@@ -114,18 +115,19 @@ void pubkey_sign_okx ( struct pubkey_sign_test *test, const char *file,
|
||||
/* Test signing using private key */
|
||||
signature_len = pubkey_sign ( pubkey, &test->private, digest,
|
||||
digestout, signature );
|
||||
okx ( signature_len == ( ( int ) test->signature_len ), file, line );
|
||||
okx ( memcmp ( signature, test->signature, test->signature_len ) == 0,
|
||||
file, line );
|
||||
okx ( signature_len == ( ( int ) test->signature.len ), file, line );
|
||||
okx ( memcmp ( signature, test->signature.data,
|
||||
test->signature.len ) == 0, file, line );
|
||||
|
||||
/* Test verification using public key */
|
||||
okx ( pubkey_verify ( pubkey, &test->public, digest, digestout,
|
||||
test->signature, test->signature_len ) == 0,
|
||||
file, line );
|
||||
&test->signature ) == 0, file, line );
|
||||
|
||||
/* Test verification failure of modified signature */
|
||||
memcpy ( bad, test->signature, test->signature_len );
|
||||
bad[ test->signature_len / 2 ] ^= 0x40;
|
||||
memcpy ( bad, test->signature.data, test->signature.len );
|
||||
bad[ test->signature.len / 2 ] ^= 0x40;
|
||||
cursor.data = bad;
|
||||
cursor.len = test->signature.len;
|
||||
okx ( pubkey_verify ( pubkey, &test->public, digest, digestout,
|
||||
bad, sizeof ( bad ) ) != 0, file, line );
|
||||
&cursor ) != 0, file, line );
|
||||
}
|
||||
|
||||
@@ -45,9 +45,7 @@ struct pubkey_sign_test {
|
||||
/** Signature algorithm */
|
||||
struct digest_algorithm *digest;
|
||||
/** Signature */
|
||||
const void *signature;
|
||||
/** Signature length */
|
||||
size_t signature_len;
|
||||
const struct asn1_cursor signature;
|
||||
};
|
||||
|
||||
/** Define inline private key data */
|
||||
@@ -129,8 +127,10 @@ struct pubkey_sign_test {
|
||||
.plaintext = name ## _plaintext, \
|
||||
.plaintext_len = sizeof ( name ## _plaintext ), \
|
||||
.digest = DIGEST, \
|
||||
.signature = name ## _signature, \
|
||||
.signature_len = sizeof ( name ## _signature ), \
|
||||
.signature = { \
|
||||
.data = name ## _signature, \
|
||||
.len = sizeof ( name ## _signature ), \
|
||||
}, \
|
||||
}
|
||||
|
||||
extern void pubkey_okx ( struct pubkey_test *test,
|
||||
|
||||
Reference in New Issue
Block a user