keymat_v2: Pass/receive signature schemes as signature_param_t objects

This commit is contained in:
Tobias Brunner
2017-11-08 16:48:10 +01:00
parent 634c6ba8ce
commit 84b1c06d0e
2 changed files with 58 additions and 28 deletions
@@ -120,7 +120,7 @@ static array_t *select_signature_schemes(keymat_v2_t *keymat,
bool have_config = FALSE; bool have_config = FALSE;
array_t *selected; array_t *selected;
selected = array_create(sizeof(signature_scheme_t), 0); selected = array_create(0, 0);
key_type = private->get_type(private); key_type = private->get_type(private);
enumerator = auth->create_enumerator(auth); enumerator = auth->create_enumerator(auth);
while (enumerator->enumerate(enumerator, &rule, &config)) while (enumerator->enumerate(enumerator, &rule, &config))
@@ -135,8 +135,7 @@ static array_t *select_signature_schemes(keymat_v2_t *keymat,
hasher_from_signature_scheme(config->scheme, hasher_from_signature_scheme(config->scheme,
config->params))) config->params)))
{ {
scheme = config->scheme; array_insert(selected, ARRAY_TAIL, signature_params_clone(config));
array_insert(selected, ARRAY_TAIL, &scheme);
} }
} }
enumerator->destroy(enumerator); enumerator->destroy(enumerator);
@@ -153,7 +152,10 @@ static array_t *select_signature_schemes(keymat_v2_t *keymat,
hasher_from_signature_scheme(scheme, hasher_from_signature_scheme(scheme,
NULL))) NULL)))
{ {
array_insert(selected, ARRAY_TAIL, &scheme); INIT(config,
.scheme = scheme,
)
array_insert(selected, ARRAY_TAIL, config);
} }
} }
enumerator->destroy(enumerator); enumerator->destroy(enumerator);
@@ -185,7 +187,10 @@ static array_t *select_signature_schemes(keymat_v2_t *keymat,
hasher_from_signature_scheme(scheme, hasher_from_signature_scheme(scheme,
NULL))) NULL)))
{ {
array_insert(selected, ARRAY_TAIL, &scheme); INIT(config,
.scheme = scheme,
)
array_insert(selected, ARRAY_TAIL, config);
} }
} }
} }
@@ -193,6 +198,12 @@ static array_t *select_signature_schemes(keymat_v2_t *keymat,
return selected; return selected;
} }
CALLBACK(destroy_scheme, void,
signature_params_t *params, int idx, void *user)
{
signature_params_destroy(params);
}
/** /**
* Create a signature using RFC 7427 signature authentication * Create a signature using RFC 7427 signature authentication
*/ */
@@ -202,7 +213,8 @@ static status_t sign_signature_auth(private_pubkey_authenticator_t *this,
{ {
enumerator_t *enumerator; enumerator_t *enumerator;
keymat_v2_t *keymat; keymat_v2_t *keymat;
signature_scheme_t scheme = SIGN_UNKNOWN, *schemep; signature_scheme_t scheme = SIGN_UNKNOWN;
signature_params_t *params;
array_t *schemes; array_t *schemes;
chunk_t octets = chunk_empty; chunk_t octets = chunk_empty;
status_t status = FAILED; status_t status = FAILED;
@@ -222,9 +234,9 @@ static status_t sign_signature_auth(private_pubkey_authenticator_t *this,
schemes)) schemes))
{ {
enumerator = array_create_enumerator(schemes); enumerator = array_create_enumerator(schemes);
while (enumerator->enumerate(enumerator, &schemep)) while (enumerator->enumerate(enumerator, &params))
{ {
scheme = *schemep; scheme = params->scheme;
if (private->sign(private, scheme, NULL, octets, auth_data) && if (private->sign(private, scheme, NULL, octets, auth_data) &&
build_signature_auth_data(auth_data, scheme)) build_signature_auth_data(auth_data, scheme))
{ {
@@ -243,7 +255,7 @@ static status_t sign_signature_auth(private_pubkey_authenticator_t *this,
DBG1(DBG_IKE, "authentication of '%Y' (myself) with %N %s", id, DBG1(DBG_IKE, "authentication of '%Y' (myself) with %N %s", id,
signature_scheme_names, scheme, signature_scheme_names, scheme,
status == SUCCESS ? "successful" : "failed"); status == SUCCESS ? "successful" : "failed");
array_destroy(schemes); array_destroy_function(schemes, destroy_scheme, NULL);
chunk_free(&octets); chunk_free(&octets);
return status; return status;
} }
@@ -254,23 +266,27 @@ static status_t sign_signature_auth(private_pubkey_authenticator_t *this,
*/ */
static bool get_auth_octets_scheme(private_pubkey_authenticator_t *this, static bool get_auth_octets_scheme(private_pubkey_authenticator_t *this,
bool verify, identification_t *id, bool verify, identification_t *id,
chunk_t *octets, signature_scheme_t *scheme) chunk_t *octets, signature_params_t **scheme)
{ {
keymat_v2_t *keymat; keymat_v2_t *keymat;
array_t *schemes; array_t *schemes;
bool success = FALSE; bool success = FALSE;
schemes = array_create(sizeof(signature_scheme_t), 0); schemes = array_create(0, 0);
array_insert(schemes, ARRAY_TAIL, scheme); array_insert(schemes, ARRAY_TAIL, *scheme);
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 (keymat->get_auth_octets(keymat, verify, this->ike_sa_init, this->nonce, if (keymat->get_auth_octets(keymat, verify, this->ike_sa_init, this->nonce,
id, this->reserved, octets, schemes) && id, this->reserved, octets, schemes) &&
array_get(schemes, 0, &scheme)) array_remove(schemes, 0, scheme))
{ {
success = TRUE; success = TRUE;
} }
array_destroy(schemes); else
{
*scheme = NULL;
}
array_destroy_function(schemes, destroy_scheme, NULL);
return success; return success;
} }
@@ -283,6 +299,7 @@ static status_t sign_classic(private_pubkey_authenticator_t *this,
chunk_t *auth_data) chunk_t *auth_data)
{ {
signature_scheme_t scheme; signature_scheme_t scheme;
signature_params_t *params;
chunk_t octets = chunk_empty; chunk_t octets = chunk_empty;
status_t status = FAILED; status_t status = FAILED;
@@ -320,11 +337,18 @@ static status_t sign_classic(private_pubkey_authenticator_t *this,
return FAILED; return FAILED;
} }
if (get_auth_octets_scheme(this, FALSE, id, &octets, &scheme) && INIT(params,
private->sign(private, scheme, NULL, octets, auth_data)) .scheme = scheme,
);
if (get_auth_octets_scheme(this, FALSE, id, &octets, &params) &&
private->sign(private, params->scheme, NULL, octets, auth_data))
{ {
status = SUCCESS; status = SUCCESS;
} }
if (params)
{
signature_params_destroy(params);
}
DBG1(DBG_IKE, "authentication of '%Y' (myself) with %N %s", id, DBG1(DBG_IKE, "authentication of '%Y' (myself) with %N %s", id,
auth_method_names, *auth_method, auth_method_names, *auth_method,
status == SUCCESS ? "successful" : "failed"); status == SUCCESS ? "successful" : "failed");
@@ -386,7 +410,8 @@ METHOD(authenticator_t, process, status_t,
auth_cfg_t *auth, *current_auth; auth_cfg_t *auth, *current_auth;
enumerator_t *enumerator; enumerator_t *enumerator;
key_type_t key_type = KEY_ECDSA; key_type_t key_type = KEY_ECDSA;
signature_params_t params; signature_scheme_t scheme;
signature_params_t *params;
status_t status = NOT_FOUND; status_t status = NOT_FOUND;
const char *reason = "unsupported"; const char *reason = "unsupported";
bool online; bool online;
@@ -402,19 +427,19 @@ METHOD(authenticator_t, process, status_t,
{ {
case AUTH_RSA: case AUTH_RSA:
key_type = KEY_RSA; key_type = KEY_RSA;
params.scheme = SIGN_RSA_EMSA_PKCS1_SHA1; scheme = SIGN_RSA_EMSA_PKCS1_SHA1;
break; break;
case AUTH_ECDSA_256: case AUTH_ECDSA_256:
params.scheme = SIGN_ECDSA_256; scheme = SIGN_ECDSA_256;
break; break;
case AUTH_ECDSA_384: case AUTH_ECDSA_384:
params.scheme = SIGN_ECDSA_384; scheme = SIGN_ECDSA_384;
break; break;
case AUTH_ECDSA_521: case AUTH_ECDSA_521:
params.scheme = SIGN_ECDSA_521; scheme = SIGN_ECDSA_521;
break; break;
case AUTH_DS: case AUTH_DS:
if (parse_signature_auth_data(&auth_data, &key_type, &params.scheme)) if (parse_signature_auth_data(&auth_data, &key_type, &scheme))
{ {
break; break;
} }
@@ -426,7 +451,10 @@ METHOD(authenticator_t, process, status_t,
return INVALID_ARG; return INVALID_ARG;
} }
id = this->ike_sa->get_other_id(this->ike_sa); id = this->ike_sa->get_other_id(this->ike_sa);
if (!get_auth_octets_scheme(this, TRUE, id, &octets, &params.scheme)) INIT(params,
.scheme = scheme,
);
if (!get_auth_octets_scheme(this, TRUE, id, &octets, &params))
{ {
return FAILED; return FAILED;
} }
@@ -437,16 +465,16 @@ METHOD(authenticator_t, process, status_t,
key_type, id, auth, online); key_type, id, auth, online);
while (enumerator->enumerate(enumerator, &public, &current_auth)) while (enumerator->enumerate(enumerator, &public, &current_auth))
{ {
if (public->verify(public, params.scheme, NULL, octets, auth_data)) if (public->verify(public, params->scheme, NULL, octets, auth_data))
{ {
DBG1(DBG_IKE, "authentication of '%Y' with %N successful", id, DBG1(DBG_IKE, "authentication of '%Y' with %N successful", id,
auth_method == AUTH_DS ? signature_scheme_names : auth_method_names, auth_method == AUTH_DS ? signature_scheme_names : auth_method_names,
auth_method == AUTH_DS ? params.scheme : auth_method); auth_method == AUTH_DS ? params->scheme : auth_method);
status = SUCCESS; status = SUCCESS;
auth->merge(auth, current_auth, FALSE); auth->merge(auth, current_auth, FALSE);
auth->add(auth, AUTH_RULE_AUTH_CLASS, AUTH_CLASS_PUBKEY); auth->add(auth, AUTH_RULE_AUTH_CLASS, AUTH_CLASS_PUBKEY);
auth->add(auth, AUTH_RULE_IKE_SIGNATURE_SCHEME, auth->add(auth, AUTH_RULE_IKE_SIGNATURE_SCHEME,
signature_params_clone(&params)); signature_params_clone(params));
if (!online) if (!online)
{ {
auth->add(auth, AUTH_RULE_CERT_VALIDATION_SUSPENDED, TRUE); auth->add(auth, AUTH_RULE_CERT_VALIDATION_SUSPENDED, TRUE);
@@ -461,6 +489,7 @@ METHOD(authenticator_t, process, status_t,
} }
enumerator->destroy(enumerator); enumerator->destroy(enumerator);
chunk_free(&octets); chunk_free(&octets);
signature_params_destroy(params);
if (status == NOT_FOUND) if (status == NOT_FOUND)
{ {
DBG1(DBG_IKE, "no trusted %N public key found for '%Y'", DBG1(DBG_IKE, "no trusted %N public key found for '%Y'",
+3 -2
View File
@@ -101,8 +101,9 @@ struct keymat_v2_t {
* @param id identity * @param id identity
* @param reserved reserved bytes of id_payload * @param reserved reserved bytes of id_payload
* @param octests chunk receiving allocated auth octets * @param octests chunk receiving allocated auth octets
* @param schemes array containing signature schemes in case they * @param schemes array containing signature schemes
* need to be modified by the keymat implementation * (signature_params_t*) in case they need to be
* modified by the keymat implementation
* @return TRUE if octets created successfully * @return TRUE if octets created successfully
*/ */
bool (*get_auth_octets)(keymat_v2_t *this, bool verify, chunk_t ike_sa_init, bool (*get_auth_octets)(keymat_v2_t *this, bool verify, chunk_t ike_sa_init,