aboutsummaryrefslogtreecommitdiffstats
path: root/src/lib/pubkey/dl_group
diff options
context:
space:
mode:
authorJack Lloyd <[email protected]>2017-01-06 15:14:01 -0500
committerJack Lloyd <[email protected]>2017-01-06 15:14:01 -0500
commitc89a4a70fddb8d623b11dcbcb17daca772c27f91 (patch)
tree6b54f7f93e4e9222f6dd22d12e3efb5b1df3fa0c /src/lib/pubkey/dl_group
parentb553d67bcfcac8020bdb720a9bd0680584ddaf77 (diff)
Fix how DL_Group chooses generator for strong prime groups.
Previously it fixed g=2 but this is not always correct. GH #784 Change default PEM header for X9.42 groups to match OpenSSL. We accept either on decoding. GH #784 Change {DL_Group,EC_Group}::PEM_for_named_curve to return std::string instead of a const char*. That makes a future refactoring I have in mind possible without breaking API.
Diffstat (limited to 'src/lib/pubkey/dl_group')
-rw-r--r--src/lib/pubkey/dl_group/dl_group.cpp23
-rw-r--r--src/lib/pubkey/dl_group/dl_group.h2
-rw-r--r--src/lib/pubkey/dl_group/dl_named.cpp4
3 files changed, 22 insertions, 7 deletions
diff --git a/src/lib/pubkey/dl_group/dl_group.cpp b/src/lib/pubkey/dl_group/dl_group.cpp
index adf207b43..6d7f0b107 100644
--- a/src/lib/pubkey/dl_group/dl_group.cpp
+++ b/src/lib/pubkey/dl_group/dl_group.cpp
@@ -29,9 +29,9 @@ DL_Group::DL_Group()
*/
DL_Group::DL_Group(const std::string& name)
{
- const char* pem = PEM_for_named_group(name);
+ const std::string pem = PEM_for_named_group(name);
- if(!pem)
+ if(pem == "")
throw Invalid_Argument("DL_Group: Unknown group " + name);
PEM_decode(pem);
@@ -52,6 +52,21 @@ DL_Group::DL_Group(RandomNumberGenerator& rng,
m_p = random_safe_prime(rng, pbits);
m_q = (m_p - 1) / 2;
m_g = 2;
+
+ /*
+ Always choose a generator that is quadratic reside mod p,
+ this forces g to be a generator of the subgroup of size q.
+ */
+ if(jacobi(m_g, m_p) != 1)
+ {
+ // prime table does not contain 2
+ for(size_t i = 0; i < PRIME_TABLE_SIZE; ++i)
+ {
+ m_g = PRIMES[i];
+ if(jacobi(m_g, m_p) == 1)
+ break;
+ }
+ }
}
else if(type == Prime_Subgroup)
{
@@ -259,7 +274,7 @@ std::string DL_Group::PEM_encode(Format format) const
else if(format == ANSI_X9_57)
return PEM_Code::encode(encoding, "DSA PARAMETERS");
else if(format == ANSI_X9_42)
- return PEM_Code::encode(encoding, "X942 DH PARAMETERS");
+ return PEM_Code::encode(encoding, "X9.42 DH PARAMETERS");
else
throw Invalid_Argument("Unknown DL_Group encoding " + std::to_string(format));
}
@@ -314,7 +329,7 @@ void DL_Group::PEM_decode(const std::string& pem)
BER_decode(ber, PKCS_3);
else if(label == "DSA PARAMETERS")
BER_decode(ber, ANSI_X9_57);
- else if(label == "X942 DH PARAMETERS")
+ else if(label == "X942 DH PARAMETERS" || label == "X9.42 DH PARAMETERS")
BER_decode(ber, ANSI_X9_42);
else
throw Decoding_Error("DL_Group: Invalid PEM label " + label);
diff --git a/src/lib/pubkey/dl_group/dl_group.h b/src/lib/pubkey/dl_group/dl_group.h
index 98a49649c..7cbf81c20 100644
--- a/src/lib/pubkey/dl_group/dl_group.h
+++ b/src/lib/pubkey/dl_group/dl_group.h
@@ -155,7 +155,7 @@ class BOTAN_DLL DL_Group
/**
* Return PEM representation of named DL group
*/
- static const char* PEM_for_named_group(const std::string& name);
+ static std::string PEM_for_named_group(const std::string& name);
private:
static BigInt make_dsa_generator(const BigInt&, const BigInt&);
diff --git a/src/lib/pubkey/dl_group/dl_named.cpp b/src/lib/pubkey/dl_group/dl_named.cpp
index 56871657e..4df9732be 100644
--- a/src/lib/pubkey/dl_group/dl_named.cpp
+++ b/src/lib/pubkey/dl_group/dl_named.cpp
@@ -9,7 +9,7 @@
namespace Botan {
-const char* DL_Group::PEM_for_named_group(const std::string& name)
+std::string DL_Group::PEM_for_named_group(const std::string& name)
{
if(name == "modp/ietf/1024")
return
@@ -354,7 +354,7 @@ const char* DL_Group::PEM_for_named_group(const std::string& name)
"eMFVkc39EVZP+I/zi3IdQjkv2kcyEtz9jS2IqXagCv/m//tDCjWeZMorNRyiQSOU"
"-----END DSA PARAMETERS-----";
- return nullptr;
+ return "";
}
}