pluto supports ECDSA authentication
This commit is contained in:
@@ -25,13 +25,13 @@ ENUM(key_type_names, KEY_RSA, KEY_DSA,
|
||||
|
||||
ENUM(signature_scheme_names, SIGN_UNKNOWN, SIGN_ECDSA_521,
|
||||
"UNKNOWN",
|
||||
"DEFAULT",
|
||||
"RSA_EMSA_PKCS1_NULL",
|
||||
"RSA_EMSA_PKCS1_MD5",
|
||||
"RSA_EMSA_PKCS1_SHA1",
|
||||
"RSA_EMSA_PKCS1_SHA256",
|
||||
"RSA_EMSA_PKCS1_SHA384",
|
||||
"RSA_EMSA_PKCS1_SHA512",
|
||||
"ECDSA_WITH_NULL",
|
||||
"ECDSA_WITH_SHA1",
|
||||
"ECDSA-256",
|
||||
"ECDSA-384",
|
||||
|
||||
@@ -60,8 +60,6 @@ extern enum_name_t *key_type_names;
|
||||
enum signature_scheme_t {
|
||||
/** Unknown signature scheme */
|
||||
SIGN_UNKNOWN,
|
||||
/** Default scheme of the underlying crypto system */
|
||||
SIGN_DEFAULT,
|
||||
/** EMSA-PKCS1_v1.5 signature over digest without digestInfo */
|
||||
SIGN_RSA_EMSA_PKCS1_NULL,
|
||||
/** EMSA-PKCS1_v1.5 signature as in PKCS#1 using RSA and MD5 */
|
||||
@@ -74,6 +72,8 @@ enum signature_scheme_t {
|
||||
SIGN_RSA_EMSA_PKCS1_SHA384,
|
||||
/** EMSA-PKCS1_v1.5 signature as in PKCS#1 using RSA and SHA-512 */
|
||||
SIGN_RSA_EMSA_PKCS1_SHA512,
|
||||
/** ECDSA over precomputed digest */
|
||||
SIGN_ECDSA_WITH_NULL,
|
||||
/** ECDSA with SHA-1 */
|
||||
SIGN_ECDSA_WITH_SHA1,
|
||||
/** ECDSA on the P-256 curve with SHA-256 as in RFC 4754 */
|
||||
|
||||
@@ -269,7 +269,7 @@ static bool sign(private_agent_private_key_t *this, signature_scheme_t scheme,
|
||||
char buf[2048];
|
||||
chunk_t blob = chunk_from_buf(buf);
|
||||
|
||||
if (scheme != SIGN_DEFAULT && scheme != SIGN_RSA_EMSA_PKCS1_SHA1)
|
||||
if (scheme != SIGN_RSA_EMSA_PKCS1_SHA1)
|
||||
{
|
||||
DBG1("signature scheme %N not supported by ssh-agent",
|
||||
signature_scheme_names, scheme);
|
||||
|
||||
@@ -144,8 +144,6 @@ static bool sign(private_gcrypt_rsa_private_key_t *this, signature_scheme_t sche
|
||||
{
|
||||
switch (scheme)
|
||||
{
|
||||
case SIGN_DEFAULT:
|
||||
/* default is EMSA-PKCS1 using SHA1 */
|
||||
case SIGN_RSA_EMSA_PKCS1_SHA1:
|
||||
return sign_pkcs1(this, HASH_SHA1, "sha1", data, sig);
|
||||
case SIGN_RSA_EMSA_PKCS1_SHA256:
|
||||
|
||||
@@ -138,8 +138,6 @@ static bool verify(private_gcrypt_rsa_public_key_t *this,
|
||||
return verify_pkcs1(this, HASH_SHA384, "sha384", data, signature);
|
||||
case SIGN_RSA_EMSA_PKCS1_SHA512:
|
||||
return verify_pkcs1(this, HASH_SHA512, "sha512", data, signature);
|
||||
case SIGN_DEFAULT:
|
||||
/* parsing hash OID currently not supported by gcrypt, fall */
|
||||
default:
|
||||
DBG1("signature scheme %N not supported in RSA",
|
||||
signature_scheme_names, scheme);
|
||||
|
||||
@@ -292,7 +292,6 @@ static bool sign(private_gmp_rsa_private_key_t *this, signature_scheme_t scheme,
|
||||
{
|
||||
case SIGN_RSA_EMSA_PKCS1_NULL:
|
||||
return build_emsa_pkcs1_signature(this, HASH_UNKNOWN, data, signature);
|
||||
case SIGN_DEFAULT:
|
||||
case SIGN_RSA_EMSA_PKCS1_SHA1:
|
||||
return build_emsa_pkcs1_signature(this, HASH_SHA1, data, signature);
|
||||
case SIGN_RSA_EMSA_PKCS1_SHA256:
|
||||
|
||||
@@ -299,7 +299,6 @@ static bool verify(private_gmp_rsa_public_key_t *this, signature_scheme_t scheme
|
||||
{
|
||||
switch (scheme)
|
||||
{
|
||||
case SIGN_DEFAULT:
|
||||
case SIGN_RSA_EMSA_PKCS1_NULL:
|
||||
return verify_emsa_pkcs1_signature(this, HASH_UNKNOWN, data, signature);
|
||||
case SIGN_RSA_EMSA_PKCS1_MD5:
|
||||
|
||||
@@ -128,36 +128,18 @@ static bool sig2chunk(const EC_GROUP *group, ECDSA_SIG *sig, chunk_t *chunk)
|
||||
* Build the signature
|
||||
*/
|
||||
static bool build_signature(private_openssl_ec_private_key_t *this,
|
||||
int hash_type, chunk_t data, chunk_t *signature)
|
||||
chunk_t hash, chunk_t *signature)
|
||||
{
|
||||
chunk_t hash = chunk_empty;
|
||||
ECDSA_SIG *sig;
|
||||
bool ret = FALSE;
|
||||
|
||||
if (!openssl_hash_chunk(hash_type, data, &hash))
|
||||
ECDSA_SIG *sig = ECDSA_do_sign(hash.ptr, hash.len, this->ec);
|
||||
bool success;
|
||||
|
||||
if (!sig)
|
||||
{
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
sig = ECDSA_do_sign(hash.ptr, hash.len, this->ec);
|
||||
if (!sig)
|
||||
{
|
||||
goto error;
|
||||
}
|
||||
|
||||
if (!sig2chunk(EC_KEY_get0_group(this->ec), sig, signature))
|
||||
{
|
||||
goto error;
|
||||
}
|
||||
|
||||
ret = TRUE;
|
||||
error:
|
||||
chunk_free(&hash);
|
||||
if (sig)
|
||||
{
|
||||
ECDSA_SIG_free(sig);
|
||||
}
|
||||
return ret;
|
||||
success = sig2chunk(EC_KEY_get0_group(this->ec), sig, signature);
|
||||
ECDSA_SIG_free(sig);
|
||||
return success;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -174,36 +156,51 @@ static key_type_t get_type(private_openssl_ec_private_key_t *this)
|
||||
static bool sign(private_openssl_ec_private_key_t *this, signature_scheme_t scheme,
|
||||
chunk_t data, chunk_t *signature)
|
||||
{
|
||||
EC_GROUP *req_group;
|
||||
const EC_GROUP *my_group;
|
||||
int hash, curve;
|
||||
|
||||
if (!lookup_scheme(scheme, &hash, &curve))
|
||||
bool success;
|
||||
|
||||
if (scheme == SIGN_ECDSA_WITH_NULL)
|
||||
{
|
||||
DBG1("signature scheme %N not supported in EC",
|
||||
signature_scheme_names, scheme);
|
||||
return FALSE;
|
||||
success = build_signature(this, data, signature);
|
||||
}
|
||||
|
||||
req_group = EC_GROUP_new_by_curve_name(curve);
|
||||
if (!req_group)
|
||||
else
|
||||
{
|
||||
DBG1("signature scheme %N not supported in EC (required curve not supported)",
|
||||
signature_scheme_names, scheme);
|
||||
return FALSE;
|
||||
}
|
||||
EC_GROUP *req_group;
|
||||
const EC_GROUP *my_group;
|
||||
chunk_t hash = chunk_empty;
|
||||
int hash_type, curve;
|
||||
|
||||
if (!lookup_scheme(scheme, &hash_type, &curve))
|
||||
{
|
||||
DBG1("signature scheme %N not supported in EC",
|
||||
signature_scheme_names, scheme);
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
my_group = EC_KEY_get0_group(this->ec);
|
||||
if (EC_GROUP_cmp(my_group, req_group, NULL) != 0)
|
||||
{
|
||||
DBG1("signature scheme %N not supported by private key",
|
||||
signature_scheme_names, scheme);
|
||||
return FALSE;
|
||||
}
|
||||
req_group = EC_GROUP_new_by_curve_name(curve);
|
||||
if (!req_group)
|
||||
{
|
||||
DBG1("signature scheme %N not supported in EC (required curve not supported)",
|
||||
signature_scheme_names, scheme);
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
EC_GROUP_free(req_group);
|
||||
|
||||
return build_signature(this, hash, data, signature);
|
||||
my_group = EC_KEY_get0_group(this->ec);
|
||||
if (EC_GROUP_cmp(my_group, req_group, NULL) != 0)
|
||||
{
|
||||
DBG1("signature scheme %N not supported by private key",
|
||||
signature_scheme_names, scheme);
|
||||
return FALSE;
|
||||
}
|
||||
EC_GROUP_free(req_group);
|
||||
|
||||
if (!openssl_hash_chunk(hash_type, data, &hash))
|
||||
{
|
||||
return FALSE;
|
||||
}
|
||||
success = build_signature(this, hash, signature);
|
||||
chunk_free(&hash);
|
||||
}
|
||||
return success;
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -73,9 +73,16 @@ static bool verify_signature(private_openssl_ec_public_key_t *this,
|
||||
ECDSA_SIG *sig;
|
||||
bool valid = FALSE;
|
||||
|
||||
if (!openssl_hash_chunk(hash_type, data, &hash))
|
||||
if (hash_type == NID_undef)
|
||||
{
|
||||
return FALSE;
|
||||
hash = data;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (!openssl_hash_chunk(hash_type, data, &hash))
|
||||
{
|
||||
return FALSE;
|
||||
}
|
||||
}
|
||||
|
||||
sig = ECDSA_SIG_new();
|
||||
@@ -88,7 +95,6 @@ static bool verify_signature(private_openssl_ec_public_key_t *this,
|
||||
{
|
||||
goto error;
|
||||
}
|
||||
|
||||
valid = (ECDSA_do_verify(hash.ptr, hash.len, sig, this->ec) == 1);
|
||||
|
||||
error:
|
||||
@@ -96,7 +102,10 @@ error:
|
||||
{
|
||||
ECDSA_SIG_free(sig);
|
||||
}
|
||||
chunk_free(&hash);
|
||||
if (hash_type != NID_undef)
|
||||
{
|
||||
chunk_free(&hash);
|
||||
}
|
||||
return valid;
|
||||
}
|
||||
|
||||
@@ -158,6 +167,8 @@ static bool verify(private_openssl_ec_public_key_t *this, signature_scheme_t sch
|
||||
{
|
||||
switch (scheme)
|
||||
{
|
||||
case SIGN_ECDSA_WITH_NULL:
|
||||
return verify_signature(this, NID_undef, data, signature);
|
||||
case SIGN_ECDSA_WITH_SHA1:
|
||||
return verify_default_signature(this, data, signature);
|
||||
case SIGN_ECDSA_256:
|
||||
|
||||
@@ -162,7 +162,6 @@ static bool sign(private_openssl_rsa_private_key_t *this, signature_scheme_t sch
|
||||
{
|
||||
case SIGN_RSA_EMSA_PKCS1_NULL:
|
||||
return build_emsa_pkcs1_signature(this, NID_undef, data, signature);
|
||||
case SIGN_DEFAULT:
|
||||
case SIGN_RSA_EMSA_PKCS1_SHA1:
|
||||
return build_emsa_pkcs1_signature(this, NID_sha1, data, signature);
|
||||
case SIGN_RSA_EMSA_PKCS1_SHA256:
|
||||
|
||||
@@ -139,7 +139,6 @@ static bool verify(private_openssl_rsa_public_key_t *this, signature_scheme_t sc
|
||||
{
|
||||
switch (scheme)
|
||||
{
|
||||
case SIGN_DEFAULT:
|
||||
case SIGN_RSA_EMSA_PKCS1_NULL:
|
||||
return verify_emsa_pkcs1_signature(this, NID_undef, data, signature);
|
||||
case SIGN_RSA_EMSA_PKCS1_SHA1:
|
||||
|
||||
Reference in New Issue
Block a user