ikev2: Move code in pubkey authenticator's build() method into separate functions

This commit is contained in:
Tobias Brunner
2015-03-09 16:59:07 +01:00
parent 03a340c6c6
commit 708dff0700
@@ -197,42 +197,30 @@ static array_t *select_signature_schemes(keymat_v2_t *keymat,
return selected; return selected;
} }
METHOD(authenticator_t, build, status_t, /**
private_pubkey_authenticator_t *this, message_t *message) * Create a signature using RFC 7427 signature authentication
*/
static status_t sign_signature_auth(private_pubkey_authenticator_t *this,
auth_cfg_t *auth, private_key_t *private,
identification_t *id, chunk_t *auth_data)
{ {
enumerator_t *enumerator; enumerator_t *enumerator;
chunk_t octets = chunk_empty, auth_data;
status_t status = FAILED;
private_key_t *private;
identification_t *id;
auth_cfg_t *auth;
auth_payload_t *auth_payload;
auth_method_t auth_method;
signature_scheme_t scheme = SIGN_UNKNOWN, *schemep;
keymat_v2_t *keymat; keymat_v2_t *keymat;
signature_scheme_t scheme = SIGN_UNKNOWN, *schemep;
array_t *schemes; array_t *schemes;
chunk_t octets = chunk_empty;
status_t status = FAILED;
id = this->ike_sa->get_my_id(this->ike_sa);
auth = this->ike_sa->get_auth_cfg(this->ike_sa, TRUE);
private = lib->credmgr->get_private(lib->credmgr, KEY_ANY, id, auth);
if (private == NULL)
{
DBG1(DBG_IKE, "no private key found for '%Y'", id);
return NOT_FOUND;
}
keymat = (keymat_v2_t*)this->ike_sa->get_keymat(this->ike_sa); keymat = (keymat_v2_t*)this->ike_sa->get_keymat(this->ike_sa);
if (this->ike_sa->supports_extension(this->ike_sa, EXT_SIGNATURE_AUTH))
{
schemes = select_signature_schemes(keymat, auth, private); schemes = select_signature_schemes(keymat, auth, private);
if (!array_count(schemes)) if (!array_count(schemes))
{ {
DBG1(DBG_IKE, "no common hash algorithm found to create signature " DBG1(DBG_IKE, "no common hash algorithm found to create signature "
"with %N key", key_type_names, private->get_type(private)); "with %N key", key_type_names, private->get_type(private));
array_destroy(schemes); array_destroy(schemes);
return status; return FAILED;
} }
auth_method = AUTH_DS;
if (keymat->get_auth_octets(keymat, FALSE, this->ike_sa_init, if (keymat->get_auth_octets(keymat, FALSE, this->ike_sa_init,
this->nonce, id, this->reserved, &octets)) this->nonce, id, this->reserved, &octets))
{ {
@@ -240,8 +228,8 @@ METHOD(authenticator_t, build, status_t,
while (enumerator->enumerate(enumerator, &schemep)) while (enumerator->enumerate(enumerator, &schemep))
{ {
scheme = *schemep; scheme = *schemep;
if (private->sign(private, scheme, octets, &auth_data) && if (private->sign(private, scheme, octets, auth_data) &&
build_signature_auth_data(&auth_data, scheme)) build_signature_auth_data(auth_data, scheme))
{ {
status = SUCCESS; status = SUCCESS;
break; break;
@@ -255,15 +243,32 @@ METHOD(authenticator_t, build, status_t,
} }
enumerator->destroy(enumerator); enumerator->destroy(enumerator);
} }
DBG1(DBG_IKE, "authentication of '%Y' (myself) with %N %s", id,
signature_scheme_names, scheme,
status == SUCCESS ? "successful" : "failed");
array_destroy(schemes); array_destroy(schemes);
} chunk_free(&octets);
else return status;
{ }
/**
* Create a classic IKEv2 signature
*/
static status_t sign_classic(private_pubkey_authenticator_t *this,
auth_cfg_t *auth, private_key_t *private,
identification_t *id, auth_method_t *auth_method,
chunk_t *auth_data)
{
signature_scheme_t scheme;
keymat_v2_t *keymat;
chunk_t octets = chunk_empty;
status_t status = FAILED;
switch (private->get_type(private)) switch (private->get_type(private))
{ {
case KEY_RSA: case KEY_RSA:
scheme = SIGN_RSA_EMSA_PKCS1_SHA1; scheme = SIGN_RSA_EMSA_PKCS1_SHA1;
auth_method = AUTH_RSA; *auth_method = AUTH_RSA;
break; break;
case KEY_ECDSA: case KEY_ECDSA:
/* deduct the signature scheme from the keysize */ /* deduct the signature scheme from the keysize */
@@ -271,34 +276,74 @@ METHOD(authenticator_t, build, status_t,
{ {
case 256: case 256:
scheme = SIGN_ECDSA_256; scheme = SIGN_ECDSA_256;
auth_method = AUTH_ECDSA_256; *auth_method = AUTH_ECDSA_256;
break; break;
case 384: case 384:
scheme = SIGN_ECDSA_384; scheme = SIGN_ECDSA_384;
auth_method = AUTH_ECDSA_384; *auth_method = AUTH_ECDSA_384;
break; break;
case 521: case 521:
scheme = SIGN_ECDSA_521; scheme = SIGN_ECDSA_521;
auth_method = AUTH_ECDSA_521; *auth_method = AUTH_ECDSA_521;
break; break;
default: default:
DBG1(DBG_IKE, "%d bit ECDSA private key size not " DBG1(DBG_IKE, "%d bit ECDSA private key size not supported",
"supported", private->get_keysize(private)); private->get_keysize(private));
return status; return FAILED;
} }
break; break;
default: default:
DBG1(DBG_IKE, "private key of type %N not supported", DBG1(DBG_IKE, "private key of type %N not supported",
key_type_names, private->get_type(private)); key_type_names, private->get_type(private));
return status; return FAILED;
} }
keymat = (keymat_v2_t*)this->ike_sa->get_keymat(this->ike_sa);
if (keymat->get_auth_octets(keymat, FALSE, this->ike_sa_init, if (keymat->get_auth_octets(keymat, FALSE, this->ike_sa_init,
this->nonce, id, this->reserved, &octets) && this->nonce, id, this->reserved, &octets) &&
private->sign(private, scheme, octets, &auth_data)) private->sign(private, scheme, octets, auth_data))
{ {
status = SUCCESS; status = SUCCESS;
} }
DBG1(DBG_IKE, "authentication of '%Y' (myself) with %N %s", id,
auth_method_names, *auth_method,
status == SUCCESS ? "successful" : "failed");
chunk_free(&octets);
return status;
}
METHOD(authenticator_t, build, status_t,
private_pubkey_authenticator_t *this, message_t *message)
{
private_key_t *private;
identification_t *id;
auth_cfg_t *auth;
chunk_t auth_data;
status_t status;
auth_payload_t *auth_payload;
auth_method_t auth_method;
id = this->ike_sa->get_my_id(this->ike_sa);
auth = this->ike_sa->get_auth_cfg(this->ike_sa, TRUE);
private = lib->credmgr->get_private(lib->credmgr, KEY_ANY, id, auth);
if (!private)
{
DBG1(DBG_IKE, "no private key found for '%Y'", id);
return NOT_FOUND;
} }
if (this->ike_sa->supports_extension(this->ike_sa, EXT_SIGNATURE_AUTH))
{
auth_method = AUTH_DS;
status = sign_signature_auth(this, auth, private, id, &auth_data);
}
else
{
status = sign_classic(this, auth, private, id, &auth_method,
&auth_data);
}
private->destroy(private);
if (status == SUCCESS) if (status == SUCCESS)
{ {
auth_payload = auth_payload_create(); auth_payload = auth_payload_create();
@@ -307,13 +352,6 @@ METHOD(authenticator_t, build, status_t,
chunk_free(&auth_data); chunk_free(&auth_data);
message->add_payload(message, (payload_t*)auth_payload); message->add_payload(message, (payload_t*)auth_payload);
} }
DBG1(DBG_IKE, "authentication of '%Y' (myself) with %N %s", id,
auth_method == AUTH_DS ? signature_scheme_names : auth_method_names,
auth_method == AUTH_DS ? scheme : auth_method,
status == SUCCESS ? "successful" : "failed");
chunk_free(&octets);
private->destroy(private);
return status; return status;
} }