| Index: openssl/crypto/ecdsa/ecdsatest.c
|
| ===================================================================
|
| --- openssl/crypto/ecdsa/ecdsatest.c (revision 105093)
|
| +++ openssl/crypto/ecdsa/ecdsatest.c (working copy)
|
| @@ -168,10 +168,9 @@
|
| return 0;
|
| }
|
| fbytes_counter ++;
|
| - ret = BN_bn2bin(tmp, buf);
|
| - if (ret == 0 || ret != num)
|
| + if (num != BN_num_bytes(tmp) || !BN_bn2bin(tmp, buf))
|
| ret = 0;
|
| - else
|
| + else
|
| ret = 1;
|
| if (tmp)
|
| BN_free(tmp);
|
| @@ -287,9 +286,12 @@
|
| size_t crv_len = 0, n = 0;
|
| EC_KEY *eckey = NULL, *wrong_eckey = NULL;
|
| EC_GROUP *group;
|
| + ECDSA_SIG *ecdsa_sig = NULL;
|
| unsigned char digest[20], wrong_digest[20];
|
| - unsigned char *signature = NULL;
|
| - unsigned int sig_len;
|
| + unsigned char *signature = NULL;
|
| + unsigned char *sig_ptr;
|
| + unsigned char *raw_buf = NULL;
|
| + unsigned int sig_len, degree, r_len, s_len, bn_len, buf_len;
|
| int nid, ret = 0;
|
|
|
| /* fill digest values with some random data */
|
| @@ -339,7 +341,8 @@
|
| if (EC_KEY_set_group(eckey, group) == 0)
|
| goto builtin_err;
|
| EC_GROUP_free(group);
|
| - if (EC_GROUP_get_degree(EC_KEY_get0_group(eckey)) < 160)
|
| + degree = EC_GROUP_get_degree(EC_KEY_get0_group(eckey));
|
| + if (degree < 160)
|
| /* drop the curve */
|
| {
|
| EC_KEY_free(eckey);
|
| @@ -415,26 +418,89 @@
|
| }
|
| BIO_printf(out, ".");
|
| (void)BIO_flush(out);
|
| - /* modify a single byte of the signature */
|
| - offset = signature[10] % sig_len;
|
| - dirt = signature[11];
|
| - signature[offset] ^= dirt ? dirt : 1;
|
| + /* wrong length */
|
| + if (ECDSA_verify(0, digest, 20, signature, sig_len - 1,
|
| + eckey) == 1)
|
| + {
|
| + BIO_printf(out, " failed\n");
|
| + goto builtin_err;
|
| + }
|
| + BIO_printf(out, ".");
|
| + (void)BIO_flush(out);
|
| +
|
| + /* Modify a single byte of the signature: to ensure we don't
|
| + * garble the ASN1 structure, we read the raw signature and
|
| + * modify a byte in one of the bignums directly. */
|
| + sig_ptr = signature;
|
| + if ((ecdsa_sig = d2i_ECDSA_SIG(NULL, &sig_ptr, sig_len)) == NULL)
|
| + {
|
| + BIO_printf(out, " failed\n");
|
| + goto builtin_err;
|
| + }
|
| +
|
| + /* Store the two BIGNUMs in raw_buf. */
|
| + r_len = BN_num_bytes(ecdsa_sig->r);
|
| + s_len = BN_num_bytes(ecdsa_sig->s);
|
| + bn_len = (degree + 7) / 8;
|
| + if ((r_len > bn_len) || (s_len > bn_len))
|
| + {
|
| + BIO_printf(out, " failed\n");
|
| + goto builtin_err;
|
| + }
|
| + buf_len = 2 * bn_len;
|
| + if ((raw_buf = OPENSSL_malloc(buf_len)) == NULL)
|
| + goto builtin_err;
|
| + /* Pad the bignums with leading zeroes. */
|
| + memset(raw_buf, 0, buf_len);
|
| + BN_bn2bin(ecdsa_sig->r, raw_buf + bn_len - r_len);
|
| + BN_bn2bin(ecdsa_sig->s, raw_buf + buf_len - s_len);
|
| +
|
| + /* Modify a single byte in the buffer. */
|
| + offset = raw_buf[10] % buf_len;
|
| + dirt = raw_buf[11] ? raw_buf[11] : 1;
|
| + raw_buf[offset] ^= dirt;
|
| + /* Now read the BIGNUMs back in from raw_buf. */
|
| + if ((BN_bin2bn(raw_buf, bn_len, ecdsa_sig->r) == NULL) ||
|
| + (BN_bin2bn(raw_buf + bn_len, bn_len, ecdsa_sig->s) == NULL))
|
| + goto builtin_err;
|
| +
|
| + sig_ptr = signature;
|
| + sig_len = i2d_ECDSA_SIG(ecdsa_sig, &sig_ptr);
|
| if (ECDSA_verify(0, digest, 20, signature, sig_len, eckey) == 1)
|
| {
|
| BIO_printf(out, " failed\n");
|
| goto builtin_err;
|
| }
|
| + /* Sanity check: undo the modification and verify signature. */
|
| + raw_buf[offset] ^= dirt;
|
| + if ((BN_bin2bn(raw_buf, bn_len, ecdsa_sig->r) == NULL) ||
|
| + (BN_bin2bn(raw_buf + bn_len, bn_len, ecdsa_sig->s) == NULL))
|
| + goto builtin_err;
|
| +
|
| + sig_ptr = signature;
|
| + sig_len = i2d_ECDSA_SIG(ecdsa_sig, &sig_ptr);
|
| + if (ECDSA_verify(0, digest, 20, signature, sig_len, eckey) != 1)
|
| + {
|
| + BIO_printf(out, " failed\n");
|
| + goto builtin_err;
|
| + }
|
| BIO_printf(out, ".");
|
| (void)BIO_flush(out);
|
|
|
| BIO_printf(out, " ok\n");
|
| /* cleanup */
|
| + /* clean bogus errors */
|
| + ERR_clear_error();
|
| OPENSSL_free(signature);
|
| signature = NULL;
|
| EC_KEY_free(eckey);
|
| eckey = NULL;
|
| EC_KEY_free(wrong_eckey);
|
| wrong_eckey = NULL;
|
| + ECDSA_SIG_free(ecdsa_sig);
|
| + ecdsa_sig = NULL;
|
| + OPENSSL_free(raw_buf);
|
| + raw_buf = NULL;
|
| }
|
|
|
| ret = 1;
|
| @@ -443,8 +509,12 @@
|
| EC_KEY_free(eckey);
|
| if (wrong_eckey)
|
| EC_KEY_free(wrong_eckey);
|
| + if (ecdsa_sig)
|
| + ECDSA_SIG_free(ecdsa_sig);
|
| if (signature)
|
| OPENSSL_free(signature);
|
| + if (raw_buf)
|
| + OPENSSL_free(raw_buf);
|
| if (curves)
|
| OPENSSL_free(curves);
|
|
|
| @@ -490,7 +560,7 @@
|
| if (ret)
|
| ERR_print_errors(out);
|
| CRYPTO_cleanup_all_ex_data();
|
| - ERR_remove_state(0);
|
| + ERR_remove_thread_state(NULL);
|
| ERR_free_strings();
|
| CRYPTO_mem_leaks(out);
|
| if (out != NULL)
|
|
|