diff options
author | lloyd <[email protected]> | 2010-03-05 06:47:02 +0000 |
---|---|---|
committer | lloyd <[email protected]> | 2010-03-05 06:47:02 +0000 |
commit | 1b68d7e53c4bc5e6b2938194b0f7eda78a72ce43 (patch) | |
tree | da1b0482d875a48fe95e133346aee4baabcbf7cb /checks | |
parent | d4ef447dc8b3b4f40f2ab250b1c364e2f74ccfa4 (diff) |
Remove the sign() operation from the public key objects, totally replaced
by using the ops.
Add real ECDSA test vectors (two found in ANSI X9.62)
Diffstat (limited to 'checks')
-rw-r--r-- | checks/ec_tests.cpp | 80 | ||||
-rw-r--r-- | checks/ecdsa.cpp | 164 | ||||
-rw-r--r-- | checks/pk.cpp | 54 | ||||
-rw-r--r-- | checks/pk_valid.dat | 18 |
4 files changed, 113 insertions, 203 deletions
diff --git a/checks/ec_tests.cpp b/checks/ec_tests.cpp index f378de8a4..0532e35fe 100644 --- a/checks/ec_tests.cpp +++ b/checks/ec_tests.cpp @@ -847,84 +847,6 @@ void test_curve_cp_ctor() CurveGFp curve(dom_pars.get_curve()); } -/** -* The following test checks assignment operator and copy ctor for ec keys -*/ -void test_ec_key_cp_and_assignment(RandomNumberGenerator& rng) - { - std::cout << "." << std::flush; - - - std::string g_secp("024a96b5688ef573284664698968c38bb913cbfc82"); - SecureVector<byte> sv_g_secp = decode_hex ( g_secp); - BigInt bi_p_secp("0xffffffffffffffffffffffffffffffff7fffffff"); - BigInt bi_a_secp("0xffffffffffffffffffffffffffffffff7ffffffc"); - BigInt bi_b_secp("0x1c97befc54bd7a8b65acf89f81d4d4adc565fa45"); - BigInt order = BigInt("0x0100000000000000000001f4c8f927aed3ca752257"); - CurveGFp curve(bi_p_secp, bi_a_secp, bi_b_secp); - - BigInt cofactor = BigInt(1); - PointGFp p_G = OS2ECP ( sv_g_secp, curve ); - - EC_Domain_Params dom_pars = EC_Domain_Params(curve, p_G, order, cofactor); - ECDSA_PrivateKey my_priv_key(rng, dom_pars); - - std::string str_message = ("12345678901234567890abcdef12"); - SecureVector<byte> sv_message = decode_hex(str_message); - - // sign with the original key - SecureVector<byte> signature = my_priv_key.sign(sv_message.begin(), sv_message.size(), rng); - bool ver_success = my_priv_key.verify(sv_message.begin(), sv_message.size(), signature.begin(), signature.size()); - CHECK_MESSAGE(ver_success, "generated signature could not be verified positively"); - - // make a copy and sign - ECDSA_PrivateKey cp_key(my_priv_key); - SecureVector<byte> cp_sig = cp_key.sign(sv_message.begin(), sv_message.size(), rng); - - // now cross verify... - CHECK(my_priv_key.verify(sv_message.begin(), sv_message.size(), cp_sig.begin(), cp_sig.size())); - CHECK(cp_key.verify(sv_message.begin(), sv_message.size(), signature.begin(), signature.size())); - - // make an copy assignment and verify - ECDSA_PrivateKey ass_key = my_priv_key; - SecureVector<byte> ass_sig = ass_key.sign(sv_message.begin(), sv_message.size(), rng); - - // now cross verify... - CHECK(my_priv_key.verify(sv_message.begin(), sv_message.size(), ass_sig.begin(), ass_sig.size())); - CHECK(ass_key.verify(sv_message.begin(), sv_message.size(), signature.begin(), signature.size())); - } - -void test_ec_key_cast(RandomNumberGenerator& rng) - { - std::cout << "." << std::flush; - - std::string g_secp("024a96b5688ef573284664698968c38bb913cbfc82"); - SecureVector<byte> sv_g_secp = decode_hex ( g_secp); - BigInt bi_p_secp("0xffffffffffffffffffffffffffffffff7fffffff"); - BigInt bi_a_secp("0xffffffffffffffffffffffffffffffff7ffffffc"); - BigInt bi_b_secp("0x1c97befc54bd7a8b65acf89f81d4d4adc565fa45"); - BigInt order = BigInt("0x0100000000000000000001f4c8f927aed3ca752257"); - CurveGFp curve(bi_p_secp, bi_a_secp, bi_b_secp); - BigInt cofactor = BigInt(1); - PointGFp p_G = OS2ECP ( sv_g_secp, curve ); - - EC_Domain_Params dom_pars = EC_Domain_Params(curve, p_G, order, cofactor); - ECDSA_PrivateKey my_priv_key(rng, dom_pars); - ECDSA_PublicKey my_ecdsa_pub_key = my_priv_key; - - Public_Key* my_pubkey = static_cast<Public_Key*>(&my_ecdsa_pub_key); - ECDSA_PublicKey* ec_cast_back = dynamic_cast<ECDSA_PublicKey*>(my_pubkey); - - std::string str_message = ("12345678901234567890abcdef12"); - SecureVector<byte> sv_message = decode_hex(str_message); - - // sign with the original key - SecureVector<byte> signature = my_priv_key.sign(sv_message.begin(), sv_message.size(), rng); - - bool ver_success = ec_cast_back->verify(sv_message.begin(), sv_message.size(), signature.begin(), signature.size()); - CHECK_MESSAGE(ver_success, "generated signature could not be verified positively"); - } - } void do_ec_tests(RandomNumberGenerator& rng) @@ -955,8 +877,6 @@ void do_ec_tests(RandomNumberGenerator& rng) test_point_swap(rng); test_mult_sec_mass(rng); test_curve_cp_ctor(); - test_ec_key_cp_and_assignment(rng); - test_ec_key_cast(rng); std::cout << std::endl; } diff --git a/checks/ecdsa.cpp b/checks/ecdsa.cpp index 64ac4be6b..036cc4dd1 100644 --- a/checks/ecdsa.cpp +++ b/checks/ecdsa.cpp @@ -116,35 +116,6 @@ void test_hash_larger_than_n(RandomNumberGenerator& rng) std::cout << "Corrupt ECDSA signature verified, should not have\n"; } -/** -* Tests whether the the signing routine will work correctly in case the integer e -* that is constructed from the message is larger than n, the order of the base point -*/ -void test_message_larger_than_n(RandomNumberGenerator& rng) - { - std::cout << "." << std::flush; - - EC_Domain_Params dom_pars(OID("1.3.132.0.8")); - ECDSA_PrivateKey priv_key(rng, dom_pars); - std::string str_message = ("12345678901234567890abcdef1212345678901234567890abcdef1212345678901234567890abcdef12"); - - SecureVector<byte> sv_message = decode_hex(str_message); - bool thrn = false; - SecureVector<byte> signature; - try - { - signature = priv_key.sign(sv_message.begin(), sv_message.size(), rng); - } - catch (Invalid_Argument e) - { - thrn = true; - } - //cout << "signature = " << hex_encode(signature.begin(), signature.size()) << "\n"; - bool ver_success = priv_key.verify(sv_message.begin(), sv_message.size(), signature.begin(), signature.size()); - CHECK_MESSAGE(ver_success, "generated signature could not be verified positively"); - //CHECK_MESSAGE(thrn, "no exception was thrown although message to sign was too long"); - } - void test_decode_ecdsa_X509() { std::cout << "." << std::flush; @@ -187,30 +158,28 @@ void test_decode_ver_link_SHA1() void test_sign_then_ver(RandomNumberGenerator& rng) { - std::cout << "." << std::flush; + std::cout << '.' << std::flush; - std::string g_secp("024a96b5688ef573284664698968c38bb913cbfc82"); - SecureVector<byte> sv_g_secp = decode_hex(g_secp); - BigInt bi_p_secp("0xffffffffffffffffffffffffffffffff7fffffff"); - BigInt bi_a_secp("0xffffffffffffffffffffffffffffffff7ffffffc"); - BigInt bi_b_secp("0x1c97befc54bd7a8b65acf89f81d4d4adc565fa45"); - BigInt order = BigInt("0x0100000000000000000001f4c8f927aed3ca752257"); - CurveGFp curve(bi_p_secp, bi_a_secp, bi_b_secp); - BigInt cofactor = BigInt(1); - PointGFp p_G = OS2ECP ( sv_g_secp, curve ); - - EC_Domain_Params dom_pars = EC_Domain_Params(curve, p_G, order, cofactor); - ECDSA_PrivateKey my_priv_key(rng, dom_pars); - - std::string str_message = ("12345678901234567890abcdef12"); - SecureVector<byte> sv_message = decode_hex(str_message); - SecureVector<byte> signature = my_priv_key.sign(sv_message.begin(), sv_message.size(), rng); - //cout << "signature = " << hex_encode(signature.begin(), signature.size()) << "\n"; - bool ver_success = my_priv_key.verify(sv_message.begin(), sv_message.size(), signature.begin(), signature.size()); - CHECK_MESSAGE(ver_success, "generated signature could not be verified positively"); - signature[signature.size()-1] += 0x01; - bool ver_must_fail = my_priv_key.verify(sv_message.begin(), sv_message.size(), signature.begin(), signature.size()); - CHECK_MESSAGE(!ver_must_fail, "corrupted signature could be verified positively"); + EC_Domain_Params dom_pars(OID("1.3.132.0.8")); + ECDSA_PrivateKey ecdsa(rng, dom_pars); + + std::auto_ptr<PK_Signer> signer(get_pk_signer(ecdsa, "EMSA1(SHA-1)")); + + SecureVector<byte> msg = decode_hex("12345678901234567890abcdef12"); + SecureVector<byte> sig = signer->sign_message(msg, rng); + + std::auto_ptr<PK_Verifier> verifier(get_pk_verifier(ecdsa, "EMSA1(SHA-1)")); + + bool ok = verifier->verify_message(msg, sig); + + if(!ok) + std::cout << "ERROR: Could not verify ECDSA signature\n"; + + sig[0]++; + ok = verifier->verify_message(msg, sig); + + if(ok) + std::cout << "ERROR: Bogus ECDSA signature verified anyway\n"; } bool test_ec_sign(RandomNumberGenerator& rng) @@ -392,13 +361,16 @@ void test_curve_registry(RandomNumberGenerator& rng) OID oid(oids[i]); EC_Domain_Params dom_pars(oid); dom_pars.get_base_point().check_invariants(); - ECDSA_PrivateKey key(rng, dom_pars); + ECDSA_PrivateKey ecdsa(rng, dom_pars); - std::string str_message = ("12345678901234567890abcdef12"); - SecureVector<byte> sv_message = decode_hex(str_message); - SecureVector<byte> signature = key.sign(sv_message.begin(), sv_message.size(), rng); - bool ver_success = key.verify(sv_message.begin(), sv_message.size(), signature.begin(), signature.size()); - CHECK_MESSAGE(ver_success, "generated signature could not be verified positively"); + std::auto_ptr<PK_Signer> signer(get_pk_signer(ecdsa, "EMSA1(SHA-1)")); + std::auto_ptr<PK_Verifier> verifier(get_pk_verifier(ecdsa, "EMSA1(SHA-1)")); + + SecureVector<byte> msg = decode_hex("12345678901234567890abcdef12"); + SecureVector<byte> sig = signer->sign_message(msg, rng); + + if(!verifier->verify_message(msg, sig)) + std::cout << "Failed testing ECDSA sig for curve " << oids[i] << "\n"; } catch(Invalid_Argument& e) { @@ -414,28 +386,37 @@ void test_read_pkcs8(RandomNumberGenerator& rng) try { std::auto_ptr<PKCS8_PrivateKey> loaded_key(PKCS8::load_key(TEST_DATA_DIR "/wo_dompar_private.pkcs8.pem", rng)); - ECDSA_PrivateKey* loaded_ec_key = dynamic_cast<ECDSA_PrivateKey*>(loaded_key.get()); - CHECK_MESSAGE(loaded_ec_key, "the loaded key could not be converted into an ECDSA_PrivateKey"); + ECDSA_PrivateKey* ecdsa = dynamic_cast<ECDSA_PrivateKey*>(loaded_key.get()); + CHECK_MESSAGE(ecdsa, "the loaded key could not be converted into an ECDSA_PrivateKey"); + + std::auto_ptr<PK_Signer> signer(get_pk_signer(*ecdsa, "EMSA1(SHA-1)")); + + SecureVector<byte> msg = decode_hex("12345678901234567890abcdef12"); + SecureVector<byte> sig = signer->sign_message(msg, rng); - std::string str_message = ("12345678901234567890abcdef12"); - SecureVector<byte> sv_message = decode_hex(str_message); - SecureVector<byte> signature = loaded_ec_key->sign(sv_message.begin(), sv_message.size(), rng); - //cout << "signature = " << hex_encode(signature.begin(), signature.size()) << "\n"; - bool ver_success = loaded_ec_key->verify(sv_message.begin(), sv_message.size(), signature.begin(), signature.size()); - CHECK_MESSAGE(ver_success, "generated signature could not be verified positively"); + std::auto_ptr<PK_Verifier> verifier(get_pk_verifier(*ecdsa, "EMSA1(SHA-1)")); + + bool ok = verifier->verify_message(msg, sig); + + CHECK_MESSAGE(ok, "generated sig could not be verified positively"); std::auto_ptr<PKCS8_PrivateKey> loaded_key_nodp(PKCS8::load_key(TEST_DATA_DIR "/nodompar_private.pkcs8.pem", rng)); // anew in each test with unregistered domain-parameters - ECDSA_PrivateKey* loaded_ec_key_nodp = dynamic_cast<ECDSA_PrivateKey*>(loaded_key_nodp.get()); - CHECK_MESSAGE(loaded_ec_key_nodp, "the loaded key could not be converted into an ECDSA_PrivateKey"); + ECDSA_PrivateKey* ecdsa_nodp = dynamic_cast<ECDSA_PrivateKey*>(loaded_key_nodp.get()); + CHECK_MESSAGE(ecdsa_nodp, "the loaded key could not be converted into an ECDSA_PrivateKey"); + + signer.reset(get_pk_signer(*ecdsa_nodp, "EMSA1(SHA-1)")); + verifier.reset(get_pk_verifier(*ecdsa_nodp, "EMSA1(SHA-1)")); + + SecureVector<byte> signature_nodp = signer->sign_message(msg, rng); + + ok = verifier->verify_message(msg, signature_nodp); + CHECK_MESSAGE(ok, "generated signature could not be verified positively (no_dom)"); - SecureVector<byte> signature_nodp = loaded_ec_key_nodp->sign(sv_message.begin(), sv_message.size(), rng); - //cout << "signature = " << hex_encode(signature.begin(), signature.size()) << "\n"; - bool ver_success_nodp = loaded_ec_key_nodp->verify(sv_message.begin(), sv_message.size(), signature_nodp.begin(), signature_nodp.size()); - CHECK_MESSAGE(ver_success_nodp, "generated signature could not be verified positively (no_dom)"); try { - std::auto_ptr<PKCS8_PrivateKey> loaded_key_withdp(PKCS8::load_key(TEST_DATA_DIR "/withdompar_private.pkcs8.pem", rng)); + std::auto_ptr<PKCS8_PrivateKey> loaded_key_withdp( + PKCS8::load_key(TEST_DATA_DIR "/withdompar_private.pkcs8.pem", rng)); std::cout << "Unexpected success: loaded key with unknown OID\n"; } @@ -447,48 +428,12 @@ void test_read_pkcs8(RandomNumberGenerator& rng) } } -/** -* The following test tests the copy ctors and and copy-assignment operators -*/ -void test_cp_and_as_ctors(RandomNumberGenerator& rng) - { - std::cout << "." << std::flush; - - std::auto_ptr<PKCS8_PrivateKey> loaded_key(PKCS8::load_key(TEST_DATA_DIR "/wo_dompar_private.pkcs8.pem", rng)); - ECDSA_PrivateKey* loaded_ec_key = dynamic_cast<ECDSA_PrivateKey*>(loaded_key.get()); - CHECK_MESSAGE(loaded_ec_key, "the loaded key could not be converted into an ECDSA_PrivateKey"); - std::string str_message = ("12345678901234567890abcdef12"); - SecureVector<byte> sv_message = decode_hex(str_message); - SecureVector<byte> signature_1 = loaded_ec_key->sign(sv_message.begin(), sv_message.size(), rng); - //cout << "signature = " << hex_encode(signature.begin(), signature.size()) << "\n"; - - ECDSA_PrivateKey cp_priv_key(*loaded_ec_key); // priv-key, cp-ctor - SecureVector<byte> signature_2 = cp_priv_key.sign(sv_message.begin(), sv_message.size(), rng); - - ECDSA_PrivateKey as_priv_key = *loaded_ec_key; //priv-key, as-op - SecureVector<byte> signature_3 = as_priv_key.sign(sv_message.begin(), sv_message.size(), rng); - - ECDSA_PublicKey pk_1 = cp_priv_key; // pub-key, as-op - ECDSA_PublicKey pk_2(pk_1); // pub-key, cp-ctor - ECDSA_PublicKey pk_3 = pk_2; - - bool ver_success_1 = pk_1.verify(sv_message.begin(), sv_message.size(), signature_1.begin(), signature_1.size()); - - bool ver_success_2 = pk_2.verify(sv_message.begin(), sv_message.size(), signature_2.begin(), signature_2.size()); - - bool ver_success_3 = pk_3.verify(sv_message.begin(), sv_message.size(), signature_3.begin(), signature_3.size()); - - CHECK_MESSAGE((ver_success_1 && ver_success_2 && ver_success_3), "different results for copied keys"); - } - } u32bit do_ecdsa_tests(Botan::RandomNumberGenerator& rng) { std::cout << "Testing ECDSA (InSiTo unit tests): "; - test_hash_larger_than_n(rng); - //test_message_larger_than_n(); test_decode_ecdsa_X509(); test_decode_ver_link_SHA256(); test_decode_ver_link_SHA1(); @@ -498,7 +443,6 @@ u32bit do_ecdsa_tests(Botan::RandomNumberGenerator& rng) test_create_and_verify(rng); test_curve_registry(rng); test_read_pkcs8(rng); - test_cp_and_as_ctors(rng); std::cout << std::endl; diff --git a/checks/pk.cpp b/checks/pk.cpp index 1a202bd7d..33d4da0fc 100644 --- a/checks/pk.cpp +++ b/checks/pk.cpp @@ -489,6 +489,31 @@ u32bit validate_dsa_sig(const std::string& algo, return 2; } +u32bit validate_ecdsa_sig(const std::string& algo, + const std::vector<std::string>& str, + RandomNumberGenerator& rng) + { + if(str.size() != 5) + throw std::runtime_error("Invalid input from pk_valid.dat"); + +#if defined(BOTAN_HAS_ECDSA) + + EC_Domain_Params group(OIDS::lookup(str[0])); + ECDSA_PrivateKey ecdsa(group, to_bigint(str[1])); + + std::string emsa = algo.substr(6, std::string::npos); + + PK_Verifier* v = get_pk_verifier(ecdsa, emsa); + PK_Signer* s = get_pk_signer(ecdsa, emsa); + + bool failure = false; + validate_signature(v, s, algo, str[2], str[3], str[4], failure); + return (failure ? 1 : 0); +#endif + + return 2; + } + u32bit validate_dsa_ver(const std::string& algo, const std::vector<std::string>& str) { @@ -791,33 +816,36 @@ u32bit do_pk_validation_tests(const std::string& filename, try { - if(algorithm.find("DSA/") != std::string::npos) + if(algorithm.find("DSA/") == 0) new_errors = validate_dsa_sig(algorithm, substr, rng); - else if(algorithm.find("DSA_VA/") != std::string::npos) + else if(algorithm.find("DSA_VA/") == 0) new_errors = validate_dsa_ver(algorithm, substr); - else if(algorithm.find("RSAES_PKCS8/") != std::string::npos) + else if(algorithm.find("ECDSA/") == 0) + new_errors = validate_ecdsa_sig(algorithm, substr, rng); + + else if(algorithm.find("RSAES_PKCS8/") == 0) new_errors = validate_rsa_enc_pkcs8(algorithm, substr, rng); - else if(algorithm.find("RSAVA_X509/") != std::string::npos) + else if(algorithm.find("RSAVA_X509/") == 0) new_errors = validate_rsa_ver_x509(algorithm, substr); - else if(algorithm.find("RSAES/") != std::string::npos) + else if(algorithm.find("RSAES/") == 0) new_errors = validate_rsa_enc(algorithm, substr, rng); - else if(algorithm.find("RSASSA/") != std::string::npos) + else if(algorithm.find("RSASSA/") == 0) new_errors = validate_rsa_sig(algorithm, substr, rng); - else if(algorithm.find("RSAVA/") != std::string::npos) + else if(algorithm.find("RSAVA/") == 0) new_errors = validate_rsa_ver(algorithm, substr); - else if(algorithm.find("RWVA/") != std::string::npos) + else if(algorithm.find("RWVA/") == 0) new_errors = validate_rw_ver(algorithm, substr); - else if(algorithm.find("RW/") != std::string::npos) + else if(algorithm.find("RW/") == 0) new_errors = validate_rw_sig(algorithm, substr, rng); - else if(algorithm.find("NR/") != std::string::npos) + else if(algorithm.find("NR/") == 0) new_errors = validate_nr_sig(algorithm, substr, rng); - else if(algorithm.find("ElGamal/") != std::string::npos) + else if(algorithm.find("ElGamal/") == 0) new_errors = validate_elg_enc(algorithm, substr, rng); - else if(algorithm.find("DH/") != std::string::npos) + else if(algorithm.find("DH/") == 0) new_errors = validate_dh(algorithm, substr, rng); - else if(algorithm.find("DLIES/") != std::string::npos) + else if(algorithm.find("DLIES/") == 0) new_errors = validate_dlies(algorithm, substr, rng); else std::cout << "WARNING: Unknown PK algorithm " diff --git a/checks/pk_valid.dat b/checks/pk_valid.dat index 1e2a84c19..fbf3c3b45 100644 --- a/checks/pk_valid.dat +++ b/checks/pk_valid.dat @@ -4182,6 +4182,24 @@ MIG6AgEAMIGhBgcqhkjOOAQBMIGVAkAA8HR2W1fHj8t8G9/BzpO5z1Ea5YnMTwMS\ 25ECC0ED4CE7118A72D133704D002A:\ 14593FBF63EAC64976987524044D8B11AB9A95B4B75A760FE22C45A3EFD6: +# ECDSA format is group name:private key:message:nonce:signature +[ECDSA/EMSA1(SHA-1)] + +# From ANSI X9.62 +secp192r1:\ +1A8D598FC15BF0FD89030B5CB1111AEB92AE8BAF5EA475FB:\ +616263:\ +FA6DE29746BBEB7F8BB1E761F85F7DFB2983169D82FA2F4E:\ +885052380FF147B734C330C43D39B2C4A89F29B0F749FEAD\ +E9ECC78106DEF82BF1070CF1D4D804C3CB390046951DF686 + +x962_p239v1:\ +7EF7C6FABEFFFDEA864206E80B0B08A9331ED93E698561B64CA0F7777F3D:\ +616263:\ +656C7196BF87DCC5D1F1020906DF2782360D36B2DE7A17ECE37D503784AF:\ +2CB7F36803EBB9C427C58D8265F11FC5084747133078FC279DE874FBECB0\ +2EEAE988104E9C2234A3C2BEB1F53BFA5DC11FF36A875D1E3CCB1F7E45CF + # NR Format: p:q:g:y:x:message:k:output [NR/EMSA1(SHA-1)] # Trickiness: in some of these, we put a leading 0 digit on the nonce (k). This |