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