ECDSA with OpenSSL
This commit is contained in:
@@ -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;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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_ @} */
|
||||
|
||||
+82
-28
@@ -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, ¤t_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;
|
||||
+11
-10
@@ -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_ @} */
|
||||
Reference in New Issue
Block a user