ECDSA with OpenSSL

This commit is contained in:
Tobias Brunner
2008-06-10 09:08:27 +00:00
parent 2904403e96
commit ea0823dffd
28 changed files with 1456 additions and 101 deletions
+32 -8
View File
@@ -1,4 +1,5 @@
/*
* Copyright (C) 2008 Tobias Brunner
* Copyright (C) 2006 Martin Willi
* Hochschule fuer Technik Rapperswil
*
@@ -19,7 +20,7 @@
#include "authenticator.h"
#include <sa/authenticators/rsa_authenticator.h>
#include <sa/authenticators/pubkey_authenticator.h>
#include <sa/authenticators/psk_authenticator.h>
#include <sa/authenticators/eap_authenticator.h>
@@ -28,24 +29,47 @@ ENUM_BEGIN(auth_method_names, AUTH_RSA, AUTH_DSS,
"RSA signature",
"pre-shared key",
"DSS signature");
ENUM_NEXT(auth_method_names, AUTH_EAP, AUTH_EAP, AUTH_DSS,
ENUM_NEXT(auth_method_names, AUTH_ECDSA_256, AUTH_ECDSA_521, AUTH_DSS,
"ECDSA-256 signature",
"ECDSA-384 signature",
"ECDSA-521 signature");
ENUM_NEXT(auth_method_names, AUTH_EAP, AUTH_EAP, AUTH_ECDSA_521,
"EAP");
ENUM_END(auth_method_names, AUTH_EAP);
/*
/**
* Described in header.
*/
authenticator_t *authenticator_create(ike_sa_t *ike_sa, auth_method_t auth_method)
authenticator_t *authenticator_create(ike_sa_t *ike_sa, config_auth_method_t auth_method)
{
switch (auth_method)
{
case AUTH_RSA:
return (authenticator_t*)rsa_authenticator_create(ike_sa);
case AUTH_PSK:
case CONF_AUTH_PUBKEY:
return (authenticator_t*)pubkey_authenticator_create(ike_sa);
case CONF_AUTH_PSK:
return (authenticator_t*)psk_authenticator_create(ike_sa);
case AUTH_EAP:
case CONF_AUTH_EAP:
return (authenticator_t*)eap_authenticator_create(ike_sa);
default:
return NULL;
}
}
/**
* Described in header.
*/
authenticator_t *authenticator_create_from_auth_payload(ike_sa_t *ike_sa, auth_payload_t *auth_payload)
{
switch (auth_payload->get_auth_method(auth_payload))
{
case AUTH_RSA:
case AUTH_ECDSA_256:
case AUTH_ECDSA_384:
case AUTH_ECDSA_521:
return (authenticator_t*)pubkey_authenticator_create(ike_sa);
case AUTH_PSK:
return (authenticator_t*)psk_authenticator_create(ike_sa);
default:
return NULL;
}
}
+32 -4
View File
@@ -1,4 +1,5 @@
/*
* Copyright (C) 2008 Tobias Brunner
* Copyright (C) 2005-2006 Martin Willi
* Copyright (C) 2005 Jan Hutter
* Hochschule fuer Technik Rapperswil
@@ -29,6 +30,7 @@ typedef struct authenticator_t authenticator_t;
#include <library.h>
#include <sa/ike_sa.h>
#include <config/peer_cfg.h>
#include <encoding/payloads/auth_payload.h>
/**
@@ -54,6 +56,21 @@ enum auth_method_t {
*/
AUTH_DSS = 3,
/**
* ECDSA with SHA-256 on the P-256 curve as specified in RFC 4754
*/
AUTH_ECDSA_256 = 9,
/**
* ECDSA with SHA-384 on the P-384 curve as specified in RFC 4754
*/
AUTH_ECDSA_384 = 10,
/**
* ECDSA with SHA-512 on the P-521 curve as specified in RFC 4754
*/
AUTH_ECDSA_521 = 11,
/**
* EAP authentication. This value is never negotiated and therefore
* a value from private use.
@@ -70,8 +87,9 @@ extern enum_name_t *auth_method_names;
* Authenticator interface implemented by the various authenticators.
*
* Currently the following two AUTH methods are supported:
* - shared key message integrity code (AUTH_PSK)
* - RSA digital signature (AUTH_RSA)
* - shared key message integrity code
* - RSA digital signature
* - ECDSA is supported using OpenSSL
*/
struct authenticator_t {
@@ -112,13 +130,23 @@ struct authenticator_t {
};
/**
* Creates an authenticator for the specified auth method.
* Creates an authenticator for the specified auth method (as configured).
*
* @param ike_sa associated ike_sa
* @param auth_method authentication method to use for build()/verify()
*
* @return authenticator_t object
*/
authenticator_t *authenticator_create(ike_sa_t *ike_sa, auth_method_t auth_method);
authenticator_t *authenticator_create(ike_sa_t *ike_sa, config_auth_method_t auth_method);
/**
* Creates an authenticator from the given auth payload.
*
* @param ike_sa associated ike_sa
* @param auth_payload auth payload
*
* @return authenticator_t object
*/
authenticator_t *authenticator_create_from_auth_payload(ike_sa_t *ike_sa, auth_payload_t *auth_payload);
#endif /* AUTHENTICATOR_H_ @} */
@@ -1,4 +1,5 @@
/*
* Copyright (C) 2008 Tobias Brunner
* Copyright (C) 2005-2006 Martin Willi
* Copyright (C) 2005 Jan Hutter
* Hochschule fuer Technik Rapperswil
@@ -18,23 +19,23 @@
#include <string.h>
#include "rsa_authenticator.h"
#include "pubkey_authenticator.h"
#include <daemon.h>
#include <credentials/auth_info.h>
typedef struct private_rsa_authenticator_t private_rsa_authenticator_t;
typedef struct private_pubkey_authenticator_t private_pubkey_authenticator_t;
/**
* Private data of an rsa_authenticator_t object.
* Private data of an pubkey_authenticator_t object.
*/
struct private_rsa_authenticator_t {
struct private_pubkey_authenticator_t {
/**
* Public authenticator_t interface.
*/
rsa_authenticator_t public;
pubkey_authenticator_t public;
/**
* Assigned IKE_SA
@@ -51,22 +52,41 @@ extern chunk_t build_tbs_octets(chunk_t ike_sa_init, chunk_t nonce,
/**
* Implementation of authenticator_t.verify.
*/
static status_t verify(private_rsa_authenticator_t *this, chunk_t ike_sa_init,
static status_t verify(private_pubkey_authenticator_t *this, chunk_t ike_sa_init,
chunk_t my_nonce, auth_payload_t *auth_payload)
{
public_key_t *public;
auth_method_t auth_method;
chunk_t auth_data, octets;
identification_t *other_id;
prf_t *prf;
auth_info_t *auth, *current_auth;
enumerator_t *enumerator;
key_type_t key_type = KEY_ECDSA;
signature_scheme_t scheme;
status_t status = FAILED;
other_id = this->ike_sa->get_other_id(this->ike_sa);
if (auth_payload->get_auth_method(auth_payload) != AUTH_RSA)
auth_method = auth_payload->get_auth_method(auth_payload);
switch (auth_method)
{
return INVALID_ARG;
case AUTH_RSA:
/* We are currently fixed to SHA1 hashes.
* TODO: allow other hash algorithms and note it in "auth" */
key_type = KEY_RSA;
scheme = SIGN_RSA_EMSA_PKCS1_SHA1;
break;
case AUTH_ECDSA_256:
scheme = SIGN_ECDSA_256;
break;
case AUTH_ECDSA_384:
scheme = SIGN_ECDSA_384;
break;
case AUTH_ECDSA_521:
scheme = SIGN_ECDSA_521;
break;
default:
return INVALID_ARG;
}
auth_data = auth_payload->get_data(auth_payload);
prf = this->ike_sa->get_prf(this->ike_sa);
@@ -75,15 +95,13 @@ static status_t verify(private_rsa_authenticator_t *this, chunk_t ike_sa_init,
auth = this->ike_sa->get_other_auth(this->ike_sa);
enumerator = charon->credentials->create_public_enumerator(
charon->credentials, KEY_RSA, other_id, auth);
charon->credentials, key_type, other_id, auth);
while (enumerator->enumerate(enumerator, &public, &current_auth))
{
/* We are currently fixed to SHA1 hashes.
* TODO: allow other hash algorithms and note it in "auth" */
if (public->verify(public, SIGN_RSA_EMSA_PKCS1_SHA1, octets, auth_data))
if (public->verify(public, scheme, octets, auth_data))
{
DBG1(DBG_IKE, "authentication of '%D' with %N successful",
other_id, auth_method_names, AUTH_RSA);
other_id, auth_method_names, auth_method);
status = SUCCESS;
auth->merge(auth, current_auth);
break;
@@ -101,7 +119,7 @@ static status_t verify(private_rsa_authenticator_t *this, chunk_t ike_sa_init,
/**
* Implementation of authenticator_t.build.
*/
static status_t build(private_rsa_authenticator_t *this, chunk_t ike_sa_init,
static status_t build(private_pubkey_authenticator_t *this, chunk_t ike_sa_init,
chunk_t other_nonce, auth_payload_t **auth_payload)
{
chunk_t octets, auth_data;
@@ -110,37 +128,73 @@ static status_t build(private_rsa_authenticator_t *this, chunk_t ike_sa_init,
identification_t *my_id;
prf_t *prf;
auth_info_t *auth;
auth_method_t auth_method;
signature_scheme_t scheme;
my_id = this->ike_sa->get_my_id(this->ike_sa);
DBG1(DBG_IKE, "authentication of '%D' (myself) with %N",
my_id, auth_method_names, AUTH_RSA);
DBG1(DBG_IKE, "authentication of '%D' (myself) with public key", my_id);
auth = this->ike_sa->get_my_auth(this->ike_sa);
private = charon->credentials->get_private(charon->credentials, KEY_RSA,
private = charon->credentials->get_private(charon->credentials, KEY_ANY,
my_id, auth);
if (private == NULL)
{
DBG1(DBG_IKE, "no RSA private key found for '%D'", my_id);
DBG1(DBG_IKE, "no private key found for '%D'", my_id);
return NOT_FOUND;
}
switch (private->get_type(private))
{
case KEY_RSA:
/* we currently use always SHA1 for signatures,
* TODO: support other hashes depending on configuration/auth */
scheme = SIGN_RSA_EMSA_PKCS1_SHA1;
auth_method = AUTH_RSA;
break;
case KEY_ECDSA:
/* we try to deduct the signature scheme from the keysize */
switch (private->get_keysize(private))
{
case 32:
scheme = SIGN_ECDSA_256;
auth_method = AUTH_ECDSA_256;
break;
case 48:
scheme = SIGN_ECDSA_384;
auth_method = AUTH_ECDSA_384;
break;
case 66:
scheme = SIGN_ECDSA_521;
auth_method = AUTH_ECDSA_521;
break;
default:
DBG1(DBG_IKE, "ECDSA not supported by private key");
return status;
}
break;
default:
DBG1(DBG_IKE, "private key of type %N not supported",
key_type_names, private->get_type(private));
return status;
}
prf = this->ike_sa->get_prf(this->ike_sa);
prf->set_key(prf, this->ike_sa->get_skp_build(this->ike_sa));
octets = build_tbs_octets(ike_sa_init, other_nonce, my_id, prf);
/* we currently use always SHA1 for signatures,
* TODO: support other hashes depending on configuration/auth */
if (private->sign(private, SIGN_RSA_EMSA_PKCS1_SHA1, octets, &auth_data))
if (private->sign(private, scheme, octets, &auth_data))
{
auth_payload_t *payload = auth_payload_create();
payload->set_auth_method(payload, AUTH_RSA);
payload->set_auth_method(payload, auth_method);
payload->set_data(payload, auth_data);
*auth_payload = payload;
chunk_free(&auth_data);
status = SUCCESS;
DBG2(DBG_IKE, "successfully signed with RSA private key");
DBG2(DBG_IKE, "successfully built %N with private key", auth_method_names, auth_method);
}
else
{
DBG1(DBG_IKE, "building RSA signature failed");
DBG1(DBG_IKE, "building signature failed");
}
chunk_free(&octets);
private->destroy(private);
@@ -151,7 +205,7 @@ static status_t build(private_rsa_authenticator_t *this, chunk_t ike_sa_init,
/**
* Implementation of authenticator_t.destroy.
*/
static void destroy(private_rsa_authenticator_t *this)
static void destroy(private_pubkey_authenticator_t *this)
{
free(this);
}
@@ -159,9 +213,9 @@ static void destroy(private_rsa_authenticator_t *this)
/*
* Described in header.
*/
rsa_authenticator_t *rsa_authenticator_create(ike_sa_t *ike_sa)
pubkey_authenticator_t *pubkey_authenticator_create(ike_sa_t *ike_sa)
{
private_rsa_authenticator_t *this = malloc_thing(private_rsa_authenticator_t);
private_pubkey_authenticator_t *this = malloc_thing(private_pubkey_authenticator_t);
/* public functions */
this->public.authenticator_interface.verify = (status_t(*)(authenticator_t*,chunk_t,chunk_t,auth_payload_t*))verify;
@@ -1,4 +1,5 @@
/*
* Copyright (C) 2008 Tobias Brunner
* Copyright (C) 2006 Martin Willi
* Hochschule fuer Technik Rapperswil
*
@@ -16,21 +17,21 @@
*/
/**
* @defgroup rsa_authenticator rsa_authenticator
* @defgroup pubkey_authenticator pubkey_authenticator
* @{ @ingroup authenticators
*/
#ifndef RSA_AUTHENTICATOR_H_
#define RSA_AUTHENTICATOR_H_
#ifndef PUBKEY_AUTHENTICATOR_H_
#define PUBKEY_AUTHENTICATOR_H_
typedef struct rsa_authenticator_t rsa_authenticator_t;
typedef struct pubkey_authenticator_t pubkey_authenticator_t;
#include <sa/authenticators/authenticator.h>
/**
* Implementation of the authenticator_t interface using AUTH_RSA.
* Implementation of the authenticator_t interface using AUTH_PUBKEY.
*/
struct rsa_authenticator_t {
struct pubkey_authenticator_t {
/**
* Implemented authenticator_t interface.
@@ -39,11 +40,11 @@ struct rsa_authenticator_t {
};
/**
* Creates an authenticator for AUTH_RSA.
* Creates an authenticator for AUTH_PUBKEY.
*
* @param ike_sa associated ike_sa
* @return rsa_authenticator_t object
* @return pubkey_authenticator_t object
*/
rsa_authenticator_t *rsa_authenticator_create(ike_sa_t *ike_sa);
pubkey_authenticator_t *pubkey_authenticator_create(ike_sa_t *ike_sa);
#endif /* RSA_AUTHENTICATOR_H_ @} */
#endif /* PUBKEY_AUTHENTICATOR_H_ @} */
+5 -5
View File
@@ -158,7 +158,7 @@ static status_t build_auth(private_ike_auth_t *this, message_t *message)
authenticator_t *auth;
auth_payload_t *auth_payload;
peer_cfg_t *config;
auth_method_t method;
config_auth_method_t method;
status_t status;
/* create own authenticator and add auth payload */
@@ -174,7 +174,7 @@ static status_t build_auth(private_ike_auth_t *this, message_t *message)
if (auth == NULL)
{
SIG(IKE_UP_FAILED, "configured authentication method %N not supported",
auth_method_names, method);
config_auth_method_names, method);
return FAILED;
}
@@ -243,9 +243,9 @@ static status_t process_auth(private_ike_auth_t *this, message_t *message)
/* AUTH payload is missing, client wants to use EAP authentication */
return NOT_FOUND;
}
auth_method = auth_payload->get_auth_method(auth_payload);
auth = authenticator_create(this->ike_sa, auth_method);
auth = authenticator_create_from_auth_payload(this->ike_sa, auth_payload);
if (auth == NULL)
{
@@ -539,7 +539,7 @@ static status_t build_i(private_ike_auth_t *this, message_t *message)
}
config = this->ike_sa->get_peer_cfg(this->ike_sa);
if (config->get_auth_method(config) == AUTH_EAP)
if (config->get_auth_method(config) == CONF_AUTH_EAP)
{
this->eap_auth = eap_authenticator_create(this->ike_sa);
}
+1 -1
View File
@@ -105,7 +105,7 @@ static void build_certs(private_ike_cert_post_t *this, message_t *message)
peer_cfg_t *peer_cfg;
peer_cfg = this->ike_sa->get_peer_cfg(this->ike_sa);
if (peer_cfg && peer_cfg->get_auth_method(peer_cfg) == AUTH_RSA)
if (peer_cfg && peer_cfg->get_auth_method(peer_cfg) == CONF_AUTH_PUBKEY)
{
switch (peer_cfg->get_cert_policy(peer_cfg))
{