diff options
Diffstat (limited to 'src')
25 files changed, 310 insertions, 234 deletions
diff --git a/src/libstrongswan/credentials/keys/public_key.c b/src/libstrongswan/credentials/keys/public_key.c index 6ae3050a0..c94c27f0a 100644 --- a/src/libstrongswan/credentials/keys/public_key.c +++ b/src/libstrongswan/credentials/keys/public_key.c @@ -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", diff --git a/src/libstrongswan/credentials/keys/public_key.h b/src/libstrongswan/credentials/keys/public_key.h index 473a432b2..c58531b73 100644 --- a/src/libstrongswan/credentials/keys/public_key.h +++ b/src/libstrongswan/credentials/keys/public_key.h @@ -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 */ diff --git a/src/libstrongswan/plugins/agent/agent_private_key.c b/src/libstrongswan/plugins/agent/agent_private_key.c index 97ca9dcb5..ffdc6d778 100644 --- a/src/libstrongswan/plugins/agent/agent_private_key.c +++ b/src/libstrongswan/plugins/agent/agent_private_key.c @@ -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); diff --git a/src/libstrongswan/plugins/gcrypt/gcrypt_rsa_private_key.c b/src/libstrongswan/plugins/gcrypt/gcrypt_rsa_private_key.c index 4ee431a83..d622a1fe1 100644 --- a/src/libstrongswan/plugins/gcrypt/gcrypt_rsa_private_key.c +++ b/src/libstrongswan/plugins/gcrypt/gcrypt_rsa_private_key.c @@ -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: diff --git a/src/libstrongswan/plugins/gcrypt/gcrypt_rsa_public_key.c b/src/libstrongswan/plugins/gcrypt/gcrypt_rsa_public_key.c index bdb5d7feb..ad02d3a28 100644 --- a/src/libstrongswan/plugins/gcrypt/gcrypt_rsa_public_key.c +++ b/src/libstrongswan/plugins/gcrypt/gcrypt_rsa_public_key.c @@ -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); diff --git a/src/libstrongswan/plugins/gmp/gmp_rsa_private_key.c b/src/libstrongswan/plugins/gmp/gmp_rsa_private_key.c index b395a8005..dec4e46a5 100644 --- a/src/libstrongswan/plugins/gmp/gmp_rsa_private_key.c +++ b/src/libstrongswan/plugins/gmp/gmp_rsa_private_key.c @@ -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: diff --git a/src/libstrongswan/plugins/gmp/gmp_rsa_public_key.c b/src/libstrongswan/plugins/gmp/gmp_rsa_public_key.c index 725e1f991..e241dbaf7 100644 --- a/src/libstrongswan/plugins/gmp/gmp_rsa_public_key.c +++ b/src/libstrongswan/plugins/gmp/gmp_rsa_public_key.c @@ -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: diff --git a/src/libstrongswan/plugins/openssl/openssl_ec_private_key.c b/src/libstrongswan/plugins/openssl/openssl_ec_private_key.c index de9733a0c..d6b442ae9 100644 --- a/src/libstrongswan/plugins/openssl/openssl_ec_private_key.c +++ b/src/libstrongswan/plugins/openssl/openssl_ec_private_key.c @@ -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)) - { - return FALSE; - } - - sig = ECDSA_do_sign(hash.ptr, hash.len, this->ec); + ECDSA_SIG *sig = ECDSA_do_sign(hash.ptr, hash.len, this->ec); + bool success; + 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 FALSE; } - 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)) - { - DBG1("signature scheme %N not supported in EC", - signature_scheme_names, scheme); - return FALSE; - } - - req_group = EC_GROUP_new_by_curve_name(curve); - if (!req_group) + bool success; + + if (scheme == SIGN_ECDSA_WITH_NULL) { - DBG1("signature scheme %N not supported in EC (required curve not supported)", - signature_scheme_names, scheme); - return FALSE; + success = build_signature(this, data, signature); } - - my_group = EC_KEY_get0_group(this->ec); - if (EC_GROUP_cmp(my_group, req_group, NULL) != 0) + else { - DBG1("signature scheme %N not supported by private key", - 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; + } - EC_GROUP_free(req_group); + 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; + } - 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; } /** diff --git a/src/libstrongswan/plugins/openssl/openssl_ec_public_key.c b/src/libstrongswan/plugins/openssl/openssl_ec_public_key.c index 780e67529..635a106dd 100644 --- a/src/libstrongswan/plugins/openssl/openssl_ec_public_key.c +++ b/src/libstrongswan/plugins/openssl/openssl_ec_public_key.c @@ -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: diff --git a/src/libstrongswan/plugins/openssl/openssl_rsa_private_key.c b/src/libstrongswan/plugins/openssl/openssl_rsa_private_key.c index 6ed999f68..695913097 100644 --- a/src/libstrongswan/plugins/openssl/openssl_rsa_private_key.c +++ b/src/libstrongswan/plugins/openssl/openssl_rsa_private_key.c @@ -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: diff --git a/src/libstrongswan/plugins/openssl/openssl_rsa_public_key.c b/src/libstrongswan/plugins/openssl/openssl_rsa_public_key.c index f891802b3..89912f24c 100644 --- a/src/libstrongswan/plugins/openssl/openssl_rsa_public_key.c +++ b/src/libstrongswan/plugins/openssl/openssl_rsa_public_key.c @@ -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: diff --git a/src/pluto/connections.c b/src/pluto/connections.c index bdfdc10a0..2d62c81a6 100644 --- a/src/pluto/connections.c +++ b/src/pluto/connections.c @@ -997,7 +997,7 @@ add_connection(const whack_message_t *wm) if (c->alg_info_esp) alg_info_snprint(buf, sizeof(buf) ,(struct alg_info *)c->alg_info_esp); - DBG_log("esp string values: %s", buf); + DBG_log("esp proposal: %s", buf); ) if (c->alg_info_esp) { @@ -1024,7 +1024,7 @@ add_connection(const whack_message_t *wm) if (c->alg_info_ike) alg_info_snprint(buf, sizeof(buf) , (struct alg_info *)c->alg_info_ike); - DBG_log("ike string values: %s", buf); + DBG_log("ike proposal: %s", buf); ) if (c->alg_info_ike) { @@ -3301,19 +3301,25 @@ refine_host_connection(const struct state *st, const struct id *peer_id * we just used it to decode the current message! */ if (psk == NULL) + { return NULL; /* cannot determine PSK! */ + } break; case XAUTHInitPreShared: case XAUTHRespPreShared: auth_policy = POLICY_XAUTH_PSK; psk = get_preshared_secret(c); if (psk == NULL) + { return NULL; /* cannot determine PSK! */ + } break; case OAKLEY_RSA_SIG: - auth_policy = POLICY_RSASIG; + case OAKLEY_ECDSA_256: + case OAKLEY_ECDSA_384: + case OAKLEY_ECDSA_512: + auth_policy = POLICY_PUBKEY; break; - case XAUTHInitRSA: case XAUTHRespRSA: auth_policy = POLICY_XAUTH_RSASIG; break; @@ -3397,6 +3403,9 @@ refine_host_connection(const struct state *st, const struct id *peer_id break; case OAKLEY_RSA_SIG: + case OAKLEY_ECDSA_256: + case OAKLEY_ECDSA_384: + case OAKLEY_ECDSA_512: case XAUTHInitRSA: case XAUTHRespRSA: /* diff --git a/src/pluto/constants.c b/src/pluto/constants.c index ae58d907f..f96134bf3 100644 --- a/src/pluto/constants.c +++ b/src/pluto/constants.c @@ -472,7 +472,7 @@ ENUM(cert_policy_names, CERT_ALWAYS_SEND, CERT_NEVER_SEND, const char *const sa_policy_bit_names[] = { "PSK", - "RSASIG", + "PUBKEY", "ENCRYPT", "AUTHENTICATE", "COMPRESS", @@ -495,7 +495,6 @@ const char *const sa_policy_bit_names[] = { "DONTREAUTH", "BEET", "MOBIKE", - "ECDSA", "PROXY", NULL }; @@ -849,13 +848,17 @@ enum_names oakley_hash_names = /* Oakley Authentication Method attribute */ static const char *const oakley_auth_name1[] = { - "OAKLEY_PRESHARED_KEY", - "OAKLEY_DSS_SIG", - "OAKLEY_RSA_SIG", - "OAKLEY_RSA_ENC", - "OAKLEY_RSA_ENC_REV", - "OAKLEY_ELGAMAL_ENC", - "OAKLEY_ELGAMAL_ENC_REV", + "PRESHARED_KEY", + "DSS_SIG", + "RSA_SIG", + "RSA_ENC", + "RSA_ENC_REV", + "ELGAMAL_ENC", + "ELGAMAL_ENC_REV", + "ECDSA_SIG", + "ECDSA_256_SIG", + "ECDSA_384_SIG", + "ECDSA_512_SIG", }; static const char *const oakley_auth_name2[] = { @@ -879,7 +882,7 @@ static const char *const oakley_auth_name3[] = { }; static enum_names oakley_auth_names1 = - { OAKLEY_PRESHARED_KEY, OAKLEY_ELGAMAL_ENC_REV + { OAKLEY_PRESHARED_KEY, OAKLEY_ECDSA_512 , oakley_auth_name1, NULL }; static enum_names oakley_auth_names2 = @@ -1079,8 +1082,7 @@ aftoinfo(int af) } } -bool -subnetisnone(const ip_subnet *sn) +bool subnetisnone(const ip_subnet *sn) { ip_address base; @@ -1174,8 +1176,7 @@ const char *const natt_type_bitnames[] = { /* look up enum names in an enum_names */ -const char * -enum_name(enum_names *ed, unsigned long val) +const char* enum_name(enum_names *ed, unsigned long val) { enum_names *p; @@ -1237,8 +1238,7 @@ enum_search(enum_names *ed, const char *str) * Result may be in STATIC buffer! * Note: prettypolicy depends on internal details. */ -const char * -bitnamesof(const char *const table[], lset_t val) +const char* bitnamesof(const char *const table[], lset_t val) { char *p = bitnamesbuf; lset_t bit; @@ -1285,8 +1285,7 @@ bitnamesof(const char *const table[], lset_t val) /* print a policy: like bitnamesof, but it also does the non-bitfields. * Suppress the shunt and fail fields if 0. */ -const char * -prettypolicy(lset_t policy) +const char* prettypolicy(lset_t policy) { const char *bn = bitnamesof(sa_policy_bit_names , policy & ~(POLICY_SHUNT_MASK | POLICY_FAIL_MASK)); @@ -1319,8 +1318,7 @@ prettypolicy(lset_t policy) /* test a set by seeing if all bits have names */ -bool -testset(const char *const table[], lset_t val) +bool testset(const char *const table[], lset_t val) { lset_t bit; const char *const *tp; @@ -1353,8 +1351,7 @@ const char *sparse_name(sparse_names sd, unsigned long val) /* find or construct a string to describe an sparse value * Result may be in STATIC buffer! */ -const char * -sparse_val_show(sparse_names sd, unsigned long val) +const char* sparse_val_show(sparse_names sd, unsigned long val) { const char *p = sparse_name(sd, val); diff --git a/src/pluto/constants.h b/src/pluto/constants.h index 7fdf5d689..84c7b1d69 100644 --- a/src/pluto/constants.h +++ b/src/pluto/constants.h @@ -724,10 +724,10 @@ extern const char *prettypolicy(lset_t policy); /* ISAKMP auth techniques (none means never negotiate) */ #define POLICY_PSK LELEM(0) -#define POLICY_RSASIG LELEM(1) +#define POLICY_PUBKEY LELEM(1) #define POLICY_ISAKMP_SHIFT 0 /* log2(POLICY_PSK) */ -#define POLICY_ID_AUTH_MASK (POLICY_PSK | POLICY_RSASIG | POLICY_XAUTH_PSK | POLICY_XAUTH_RSASIG) +#define POLICY_ID_AUTH_MASK (POLICY_PSK | POLICY_PUBKEY | POLICY_XAUTH_PSK | POLICY_XAUTH_RSASIG) #define POLICY_ISAKMP_MASK POLICY_ID_AUTH_MASK /* all so far */ /* Quick Mode (IPSEC) attributes */ @@ -776,8 +776,7 @@ extern const char *prettypolicy(lset_t policy); #define POLICY_BEET LELEM(22) /* bound end2end tunnel, IKEv2 */ #define POLICY_MOBIKE LELEM(23) /* enable MOBIKE for IKEv2 */ #define POLICY_FORCE_ENCAP LELEM(24) /* force UDP encapsulation (IKEv2) */ -#define POLICY_ECDSASIG LELEM(25) /* ECDSA signature (IKEv2) */ -#define POLICY_PROXY LELEM(26) /* proxy transport mode (MIPv6) */ +#define POLICY_PROXY LELEM(25) /* proxy transport mode (MIPv6) */ /* Any IPsec policy? If not, a connection description * is only for ISAKMP SA, not IPSEC SA. (A pun, I admit.) @@ -979,8 +978,12 @@ extern enum_names oakley_auth_names; #define OAKLEY_RSA_ENC_REV 5 #define OAKLEY_ELGAMAL_ENC 6 #define OAKLEY_ELGAMAL_ENC_REV 7 +#define OAKLEY_ECDSA_SIG 8 +#define OAKLEY_ECDSA_256 9 +#define OAKLEY_ECDSA_384 10 +#define OAKLEY_ECDSA_512 11 -#define OAKLEY_AUTH_ROOF 8 /* roof on auth values THAT WE SUPPORT */ +#define OAKLEY_AUTH_ROOF 12 /* roof on auth values THAT WE SUPPORT */ #define HybridInitRSA 64221 #define HybridRespRSA 64222 diff --git a/src/pluto/demux.c b/src/pluto/demux.c index 53b44a0f8..83bcffb4e 100644 --- a/src/pluto/demux.c +++ b/src/pluto/demux.c @@ -188,7 +188,9 @@ struct state_microcode { */ #define SMF_ALL_AUTH LRANGE(0, OAKLEY_AUTH_ROOF-1) #define SMF_PSK_AUTH LELEM(OAKLEY_PRESHARED_KEY) -#define SMF_DS_AUTH (LELEM(OAKLEY_DSS_SIG) | LELEM(OAKLEY_RSA_SIG)) +#define SMF_DS_AUTH (LELEM(OAKLEY_DSS_SIG) | LELEM(OAKLEY_RSA_SIG) | \ + LELEM(OAKLEY_ECDSA_SIG) | LELEM(OAKLEY_ECDSA_256) | \ + LELEM(OAKLEY_ECDSA_384) | LELEM(OAKLEY_ECDSA_512)) #define SMF_PKE_AUTH (LELEM(OAKLEY_RSA_ENC) | LELEM(OAKLEY_ELGAMAL_ENC)) #define SMF_RPKE_AUTH (LELEM(OAKLEY_RSA_ENC_REV) | LELEM(OAKLEY_ELGAMAL_ENC_REV)) diff --git a/src/pluto/ike_alg.c b/src/pluto/ike_alg.c index a03612b99..17f9991df 100644 --- a/src/pluto/ike_alg.c +++ b/src/pluto/ike_alg.c @@ -30,9 +30,9 @@ #include "constants.h" #include "defs.h" #include "crypto.h" - #include "state.h" #include "packet.h" +#include "keys.h" #include "log.h" #include "whack.h" #include "spdb.h" @@ -141,8 +141,9 @@ const struct dh_desc *ike_alg_pfsgroup(struct connection *c, lset_t policy) /** * Create an OAKLEY proposal based on alg_info and policy */ -struct db_context *ike_alg_db_new(struct alg_info_ike *ai , lset_t policy) +struct db_context *ike_alg_db_new(struct connection *c, lset_t policy) { + struct alg_info_ike *ai = c->alg_info_ike; struct db_context *db_ctx = NULL; struct ike_info *ike_info; struct encrypt_desc *enc_desc; @@ -189,14 +190,47 @@ struct db_context *ike_alg_db_new(struct alg_info_ike *ai , lset_t policy) } enc_desc = ike_alg_get_crypter(ealg); - if (policy & POLICY_RSASIG) + if (policy & POLICY_PUBKEY) { + int auth_method = 0; + private_key_t *key = get_private_key(c); + + if (key == NULL) + { + continue; + } + switch (key->get_type(key)) + { + case KEY_RSA: + auth_method = OAKLEY_RSA_SIG; + break; + case KEY_ECDSA: + switch (key->get_keysize(key)) + { + case 32: + auth_method = OAKLEY_ECDSA_256; + break; + case 48: + auth_method = OAKLEY_ECDSA_384; + break; + case 66: + auth_method = OAKLEY_ECDSA_512; + break; + default: + continue; + } + break; + default: + continue; + } db_trans_add(db_ctx, KEY_IKE); db_attr_add_values(db_ctx, OAKLEY_ENCRYPTION_ALGORITHM, ealg); db_attr_add_values(db_ctx, OAKLEY_HASH_ALGORITHM, halg); if (eklen) + { db_attr_add_values(db_ctx, OAKLEY_KEY_LENGTH, eklen); - db_attr_add_values(db_ctx, OAKLEY_AUTHENTICATION_METHOD, OAKLEY_RSA_SIG); + } + db_attr_add_values(db_ctx, OAKLEY_AUTHENTICATION_METHOD, auth_method); db_attr_add_values(db_ctx, OAKLEY_GROUP_DESCRIPTION, modp); } @@ -206,7 +240,9 @@ struct db_context *ike_alg_db_new(struct alg_info_ike *ai , lset_t policy) db_attr_add_values(db_ctx, OAKLEY_ENCRYPTION_ALGORITHM, ealg); db_attr_add_values(db_ctx, OAKLEY_HASH_ALGORITHM, halg); if (eklen) + { db_attr_add_values(db_ctx, OAKLEY_KEY_LENGTH, eklen); + } db_attr_add_values(db_ctx, OAKLEY_AUTHENTICATION_METHOD, OAKLEY_PRESHARED_KEY); db_attr_add_values(db_ctx, OAKLEY_GROUP_DESCRIPTION, modp); } @@ -217,7 +253,9 @@ struct db_context *ike_alg_db_new(struct alg_info_ike *ai , lset_t policy) db_attr_add_values(db_ctx, OAKLEY_ENCRYPTION_ALGORITHM, ealg); db_attr_add_values(db_ctx, OAKLEY_HASH_ALGORITHM, halg); if (eklen) + { db_attr_add_values(db_ctx, OAKLEY_KEY_LENGTH, eklen); + } db_attr_add_values(db_ctx, OAKLEY_AUTHENTICATION_METHOD , is_xauth_server ? XAUTHRespRSA : XAUTHInitRSA); db_attr_add_values(db_ctx, OAKLEY_GROUP_DESCRIPTION, modp); @@ -229,7 +267,9 @@ struct db_context *ike_alg_db_new(struct alg_info_ike *ai , lset_t policy) db_attr_add_values(db_ctx, OAKLEY_ENCRYPTION_ALGORITHM, ealg); db_attr_add_values(db_ctx, OAKLEY_HASH_ALGORITHM, halg); if (eklen) + { db_attr_add_values(db_ctx, OAKLEY_KEY_LENGTH, eklen); + } db_attr_add_values(db_ctx, OAKLEY_AUTHENTICATION_METHOD , is_xauth_server ? XAUTHRespPreShared : XAUTHInitPreShared); db_attr_add_values(db_ctx, OAKLEY_GROUP_DESCRIPTION, modp); diff --git a/src/pluto/ike_alg.h b/src/pluto/ike_alg.h index c4a03cf30..458d14c3a 100644 --- a/src/pluto/ike_alg.h +++ b/src/pluto/ike_alg.h @@ -62,7 +62,7 @@ extern struct hash_desc *ike_alg_get_hasher(u_int alg); extern struct encrypt_desc *ike_alg_get_crypter(u_int alg); extern struct dh_desc *ike_alg_get_dh_group(u_int alg); extern const struct dh_desc* ike_alg_pfsgroup(struct connection *c, lset_t policy); -extern struct db_context * ike_alg_db_new(struct alg_info_ike *ai, lset_t policy); +extern struct db_context * ike_alg_db_new(struct connection *c, lset_t policy); extern void ike_alg_list(void); extern void ike_alg_show_connection(struct connection *c, const char *instance); extern bool ike_alg_ok_final(u_int ealg, u_int key_len, u_int aalg, u_int group diff --git a/src/pluto/ipsec_doi.c b/src/pluto/ipsec_doi.c index 2a9d9d4c1..286b7fbc7 100644 --- a/src/pluto/ipsec_doi.c +++ b/src/pluto/ipsec_doi.c @@ -1208,6 +1208,9 @@ static bool generate_skeyids_iv(struct state *st) break; case OAKLEY_RSA_SIG: + case OAKLEY_ECDSA_256: + case OAKLEY_ECDSA_384: + case OAKLEY_ECDSA_512: case XAUTHInitRSA: case XAUTHRespRSA: if (!skeyid_digisig(st)) @@ -1354,7 +1357,7 @@ static bool generate_skeyids_iv(struct state *st) * If hashus argument is TRUE, we're generating a hash for our end. * See RFC2409 IKE 5. */ - static size_t main_mode_hash(struct state *st, u_char *hash_val, bool hashi, + static void main_mode_hash(struct state *st, chunk_t *hash, bool hashi, const pb_stream *idpl) { chunk_t icookie = { st->st_icookie, COOKIE_SIZE }; @@ -1365,9 +1368,21 @@ static bool generate_skeyids_iv(struct state *st) pbs_offset(idpl) - sizeof(struct isakmp_generic) }; pseudo_random_function_t prf_alg; prf_t *prf; - size_t prf_block_size; - prf_alg = oakley_to_prf(st->st_oakley.hash); + switch (st->st_oakley.auth) + { + case OAKLEY_ECDSA_256: + prf_alg = PRF_HMAC_SHA2_256; + break; + case OAKLEY_ECDSA_384: + prf_alg = PRF_HMAC_SHA2_384; + break; + case OAKLEY_ECDSA_512: + prf_alg = PRF_HMAC_SHA2_512; + break; + default: + prf_alg = oakley_to_prf(st->st_oakley.hash); + } prf = lib->crypto->create_prf(lib->crypto, prf_alg); prf->set_key(prf, st->st_skeyid); @@ -1396,11 +1411,9 @@ static bool generate_skeyids_iv(struct state *st) * we use the bytes as they appear on the wire to avoid * "spelling problems". */ - prf->get_bytes(prf, id_body, hash_val); - prf_block_size = prf->get_block_size(prf); + prf->get_bytes(prf, id_body, hash->ptr); + hash->len = prf->get_block_size(prf); prf->destroy(prf); - - return prf_block_size; } /* Create a public key signature of a hash. @@ -1408,30 +1421,27 @@ static bool generate_skeyids_iv(struct state *st) * Use PKCS#1 version 1.5 encryption of hash (called * RSAES-PKCS1-V1_5) in PKCS#2. */ -static size_t sign_hash(struct connection *c, u_char sig_val[RSA_MAX_OCTETS], - u_char *hash_val, size_t hash_len) +static size_t sign_hash(signature_scheme_t scheme, struct connection *c, + u_char sig_val[RSA_MAX_OCTETS], chunk_t hash) { size_t sz = 0; smartcard_t *sc = c->spd.this.sc; if (sc == NULL) /* no smartcard */ { - chunk_t hash, sig; + chunk_t sig; private_key_t *private = get_private_key(c); if (private == NULL) { return 0; /* failure: no key to use */ } - sz = private->get_keysize(private); - passert(RSA_MIN_OCTETS <= sz && 4 + hash_len < sz && sz <= RSA_MAX_OCTETS); - hash = chunk_create(hash_val, hash_len); - sig = chunk_create(sig_val, sz); - if (!private->sign(private, SIGN_RSA_EMSA_PKCS1_NULL, hash, &sig)) + if (!private->sign(private, scheme, hash, &sig)) { return 0; } - memcpy(sig_val, sig.ptr, sz); + memcpy(sig_val, sig.ptr, sig.len); + sz = sig.len; free(sig.ptr); } else if (sc->valid) /* if valid pin then sign hash on the smartcard */ @@ -1457,7 +1467,7 @@ static size_t sign_hash(struct connection *c, u_char sig_val[RSA_MAX_OCTETS], DBG_log("signing hash with RSA key from smartcard (slot: %d, id: %s)" , (int)sc->slot, sc->id) ) - sz = scx_sign_hash(sc, hash_val, hash_len, sig_val, sz) ? sz : 0; + sz = scx_sign_hash(sc, hash.ptr, hash.len, sig_val, sz) ? sz : 0; if (!pkcs11_keep_state) scx_release_context(sc); unlock_certs_and_keys("sign_hash"); @@ -1485,14 +1495,18 @@ struct tac_state { static bool take_a_crack(struct tac_state *s, pubkey_t *kr) { public_key_t *pub_key = kr->public_key; - identification_t *keyid = pub_key->get_id(pub_key, ID_PUBKEY_SHA1); + identification_t *keyid = pub_key->get_id(pub_key, ID_PUBKEY_INFO_SHA1); + signature_scheme_t scheme; + scheme = (s->st->st_oakley.auth == OAKLEY_RSA_SIG) ? + SIGN_RSA_EMSA_PKCS1_NULL : SIGN_ECDSA_WITH_NULL; s->tried_cnt++; - if (pub_key->verify(pub_key, SIGN_RSA_EMSA_PKCS1_NULL, s->hash, s->sig)) + if (pub_key->verify(pub_key, scheme, s->hash, s->sig)) { DBG(DBG_CRYPT | DBG_CONTROL, - DBG_log("signature check passed with keyid %Y", keyid) + DBG_log("%s check passed with keyid %Y", + enum_show(&oakley_auth_names, s->st->st_oakley.auth), keyid) ) unreference_key(&s->st->st_peer_pubkey); s->st->st_peer_pubkey = reference_key(kr); @@ -1501,25 +1515,26 @@ static bool take_a_crack(struct tac_state *s, pubkey_t *kr) else { DBG(DBG_CRYPT, - DBG_log("signature check failed with keyid %Y", keyid) + DBG_log("%s check failed with keyid %Y", + enum_show(&oakley_auth_names, s->st->st_oakley.auth), keyid) ) return FALSE; } } -static stf_status RSA_check_signature(const struct id* peer, struct state *st, - u_char hash_val[MAX_DIGEST_LEN], - size_t hash_len, const pb_stream *sig_pbs, +static stf_status check_signature(key_type_t key_type, const struct id* peer, + struct state *st, chunk_t hash, + const pb_stream *sig_pbs, #ifdef USE_KEYRR - const pubkey_list_t *keys_from_dns, + const pubkey_list_t *keys_from_dns, #endif /* USE_KEYRR */ - const struct gw_info *gateways_from_dns) + const struct gw_info *gateways_from_dns) { const struct connection *c = st->st_connection; struct tac_state s; s.st = st; - s.hash = chunk_create(hash_val, hash_len); + s.hash = hash; s.sig = chunk_create(sig_pbs->cur, pbs_left(sig_pbs)); s.tried_cnt = 0; @@ -1550,7 +1565,7 @@ static stf_status RSA_check_signature(const struct id* peer, struct state *st, pubkey_t *key = p->key; key_type_t type = key->public_key->get_type(key->public_key); - if (type == KEY_RSA && same_id(peer, &key->id)) + if (type == key_type && same_id(peer, &key->id)) { time_t now = time(NULL); @@ -2775,6 +2790,23 @@ static void compute_keymats(struct state *st) compute_proto_keymat(st, PROTO_IPSEC_ESP, &st->st_esp); } +static bool uses_pubkey_auth(int auth) +{ + switch (auth) + { + case OAKLEY_RSA_SIG: + case OAKLEY_ECDSA_SIG: + case OAKLEY_ECDSA_256: + case OAKLEY_ECDSA_384: + case OAKLEY_ECDSA_512: + case XAUTHInitRSA: + case XAUTHRespRSA: + return TRUE; + default: + return FALSE; + } +} + /* State Transition Functions. * * The definition of state_microcode_table in demux.c is a good @@ -3170,11 +3202,9 @@ stf_status main_inI2_outR2(struct msg_digest *md) struct state *const st = md->st; pb_stream *keyex_pbs = &md->chain[ISAKMP_NEXT_KE]->pbs; - /* send CR if auth is RSA and no preloaded RSA public key exists*/ - bool RSA_auth = st->st_oakley.auth == OAKLEY_RSA_SIG - || st->st_oakley.auth == XAUTHInitRSA - || st->st_oakley.auth == XAUTHRespRSA; - bool send_cr = !no_cr_send && RSA_auth && !has_preloaded_public_key(st); + /* send CR if auth is RSA or ECDSA and no preloaded public key exists*/ + bool pubkey_auth = uses_pubkey_auth(st->st_oakley.auth); + bool send_cr = !no_cr_send && pubkey_auth && !has_preloaded_public_key(st); u_int8_t np = ISAKMP_NEXT_NONE; @@ -3314,12 +3344,9 @@ stf_status main_inR2_outI3(struct msg_digest *md) certpolicy_t cert_policy = st->st_connection->spd.this.sendcert; cert_t mycert = st->st_connection->spd.this.cert; bool requested, send_cert, send_cr; + bool pubkey_auth = uses_pubkey_auth(st->st_oakley.auth); - bool RSA_auth = st->st_oakley.auth == OAKLEY_RSA_SIG - || st->st_oakley.auth == XAUTHInitRSA - || st->st_oakley.auth == XAUTHRespRSA; - - int auth_payload = RSA_auth ? ISAKMP_NEXT_SIG : ISAKMP_NEXT_HASH; + int auth_payload = pubkey_auth ? ISAKMP_NEXT_SIG : ISAKMP_NEXT_HASH; /* KE in */ RETURN_STF_FAILURE(accept_KE(&st->st_gr, "Gr", st->st_oakley.group, keyex_pbs)); @@ -3342,7 +3369,7 @@ stf_status main_inR2_outI3(struct msg_digest *md) */ requested = cert_policy == CERT_SEND_IF_ASKED && st->st_connection->got_certrequest; - send_cert = RSA_auth && mycert.type != CERT_NONE + send_cert = pubkey_auth && mycert.type != CERT_NONE && (cert_policy == CERT_ALWAYS_SEND || requested); /* send certificate request if we don't have a preloaded RSA public key */ @@ -3385,7 +3412,7 @@ stf_status main_inR2_outI3(struct msg_digest *md) } /* CERT out */ - if (RSA_auth) + if (pubkey_auth) { DBG(DBG_CONTROL, DBG_log("our certificate policy is %N", cert_policy_names, cert_policy) @@ -3429,23 +3456,30 @@ stf_status main_inR2_outI3(struct msg_digest *md) /* HASH_I or SIG_I out */ { - u_char hash_val[MAX_DIGEST_LEN]; - size_t hash_len = main_mode_hash(st, hash_val, TRUE, &id_pbs); + u_char hash_buf[MAX_DIGEST_LEN]; + chunk_t hash = chunk_from_buf(hash_buf); + + main_mode_hash(st, &hash, TRUE, &id_pbs); if (auth_payload == ISAKMP_NEXT_HASH) { /* HASH_I out */ - if (!out_generic_raw(ISAKMP_NEXT_NONE, &isakmp_hash_desc, &md->rbody - , hash_val, hash_len, "HASH_I")) + if (!out_generic_raw(ISAKMP_NEXT_NONE, &isakmp_hash_desc, &md->rbody, + hash.ptr, hash.len, "HASH_I")) + { return STF_INTERNAL_ERROR; + } } else { /* SIG_I out */ u_char sig_val[RSA_MAX_OCTETS]; - size_t sig_len = sign_hash(st->st_connection, sig_val, hash_val, - hash_len); + signature_scheme_t scheme; + size_t sig_len; + scheme = (st->st_oakley.auth == OAKLEY_RSA_SIG) ? + SIGN_RSA_EMSA_PKCS1_NULL : SIGN_ECDSA_WITH_NULL; + sig_len = sign_hash(scheme, st->st_connection, sig_val, hash); if (sig_len == 0) { loglog(RC_LOG_SERIOUS, "unable to locate my private key for signature"); @@ -3514,9 +3548,9 @@ main_id_and_auth(struct msg_digest *md , const struct key_continuation *kc /* current state, can be NULL */ ) { + u_char hash_buf[MAX_DIGEST_LEN]; + chunk_t hash = chunk_from_buf(hash_buf); struct state *st = md->st; - u_char hash_val[MAX_DIGEST_LEN]; - size_t hash_len; struct id peer; stf_status r = STF_OK; @@ -3533,7 +3567,7 @@ main_id_and_auth(struct msg_digest *md u_int8_t *old_cur = idpl->cur; idpl->cur = idpl->roof; - hash_len = main_mode_hash(st, hash_val, !initiator, idpl); + main_mode_hash(st, &hash, !initiator, idpl); idpl->cur = old_cur; } @@ -3545,8 +3579,8 @@ main_id_and_auth(struct msg_digest *md { pb_stream *const hash_pbs = &md->chain[ISAKMP_NEXT_HASH]->pbs; - if (pbs_left(hash_pbs) != hash_len - || memcmp(hash_pbs->cur, hash_val, hash_len) != 0) + if (pbs_left(hash_pbs) != hash.len + || memcmp(hash_pbs->cur, hash.ptr, hash.len) != 0) { DBG_cond_dump(DBG_CRYPT, "received HASH:" , hash_pbs->cur, pbs_left(hash_pbs)); @@ -3560,14 +3594,14 @@ main_id_and_auth(struct msg_digest *md case OAKLEY_RSA_SIG: case XAUTHInitRSA: case XAUTHRespRSA: - r = RSA_check_signature(&peer, st, hash_val, hash_len - , &md->chain[ISAKMP_NEXT_SIG]->pbs + r = check_signature(KEY_RSA, &peer, st, hash, + &md->chain[ISAKMP_NEXT_SIG]->pbs, #ifdef USE_KEYRR - , kc == NULL? NULL : kc->ac.keys_from_dns + kc == NULL? NULL : kc->ac.keys_from_dns, #endif /* USE_KEYRR */ - , kc == NULL? NULL : kc->ac.gateways_from_dns + kc == NULL? NULL : kc->ac.gateways_from_dns ); - + if (r == STF_SUSPEND) { /* initiate/resume asynchronous DNS lookup for key */ @@ -3622,6 +3656,17 @@ main_id_and_auth(struct msg_digest *md } break; + case OAKLEY_ECDSA_256: + case OAKLEY_ECDSA_384: + case OAKLEY_ECDSA_512: + r = check_signature(KEY_ECDSA, &peer, st, hash, + &md->chain[ISAKMP_NEXT_SIG]->pbs, +#ifdef USE_KEYRR + NULL, +#endif /* USE_KEYRR */ + NULL); + break; + default: bad_case(st->st_oakley.auth); } @@ -3732,9 +3777,7 @@ main_inI3_outR3_tail(struct msg_digest *md pb_stream r_id_pbs; /* ID Payload; also used for hash calculation */ certpolicy_t cert_policy; cert_t mycert; - bool RSA_auth; - bool send_cert; - bool requested; + bool pubkey_auth, send_cert, requested; /* ID and HASH_I or SIG_I in * Note: this may switch the connection being used! @@ -3748,19 +3791,16 @@ main_inI3_outR3_tail(struct msg_digest *md return r; } - /* send certificate if auth is RSA, we have one and we want - * or are requested to send it + /* send certificate if pubkey authentication is used, we have one + * and we want or are requested to send it */ cert_policy = st->st_connection->spd.this.sendcert; mycert = st->st_connection->spd.this.cert; requested = cert_policy == CERT_SEND_IF_ASKED && st->st_connection->got_certrequest; - RSA_auth = st->st_oakley.auth == OAKLEY_RSA_SIG - || st->st_oakley.auth == XAUTHInitRSA - || st->st_oakley.auth == XAUTHRespRSA; - send_cert = RSA_auth - && mycert.type != CERT_NONE - && (cert_policy == CERT_ALWAYS_SEND || requested); + pubkey_auth = uses_pubkey_auth(st->st_oakley.auth); + send_cert = pubkey_auth && mycert.type != CERT_NONE && + (cert_policy == CERT_ALWAYS_SEND || requested); /*************** build output packet HDR*;IDir;HASH/SIG_R ***************/ /* proccess_packet() would automatically generate the HDR* @@ -3776,7 +3816,7 @@ main_inI3_outR3_tail(struct msg_digest *md */ echo_hdr(md, TRUE, ISAKMP_NEXT_ID); - auth_payload = RSA_auth ? ISAKMP_NEXT_SIG : ISAKMP_NEXT_HASH; + auth_payload = pubkey_auth ? ISAKMP_NEXT_SIG : ISAKMP_NEXT_HASH; /* IDir out */ { @@ -3795,7 +3835,7 @@ main_inI3_outR3_tail(struct msg_digest *md } /* CERT out */ - if (RSA_auth) + if (pubkey_auth) { DBG(DBG_CONTROL, DBG_log("our certificate policy is %N", cert_policy_names, cert_policy) @@ -3831,23 +3871,30 @@ main_inI3_outR3_tail(struct msg_digest *md /* HASH_R or SIG_R out */ { - u_char hash_val[MAX_DIGEST_LEN]; - size_t hash_len = main_mode_hash(st, hash_val, FALSE, &r_id_pbs); + u_char hash_buf[MAX_DIGEST_LEN]; + chunk_t hash = chunk_from_buf(hash_buf); + + main_mode_hash(st, &hash, FALSE, &r_id_pbs); if (auth_payload == ISAKMP_NEXT_HASH) { /* HASH_R out */ - if (!out_generic_raw(ISAKMP_NEXT_NONE, &isakmp_hash_desc, &md->rbody - , hash_val, hash_len, "HASH_R")) + if (!out_generic_raw(ISAKMP_NEXT_NONE, &isakmp_hash_desc, &md->rbody, + hash.ptr, hash.len, "HASH_R")) + { return STF_INTERNAL_ERROR; + } } else { /* SIG_R out */ u_char sig_val[RSA_MAX_OCTETS]; - size_t sig_len = sign_hash(st->st_connection, sig_val, hash_val, - hash_len); + signature_scheme_t scheme; + size_t sig_len; + scheme = (st->st_oakley.auth == OAKLEY_RSA_SIG) ? + SIGN_RSA_EMSA_PKCS1_NULL : SIGN_ECDSA_WITH_NULL; + sig_len = sign_hash(scheme, st->st_connection, sig_val, hash); if (sig_len == 0) { loglog(RC_LOG_SERIOUS, "unable to locate my private key for signature"); diff --git a/src/pluto/kernel_alg.c b/src/pluto/kernel_alg.c index d5301c61b..1590bdf02 100644 --- a/src/pluto/kernel_alg.c +++ b/src/pluto/kernel_alg.c @@ -660,20 +660,14 @@ struct db_context* kernel_alg_db_new(struct alg_info_esp *alg_info, { const struct esp_info *esp_info; struct esp_info tmp_esp_info; - struct db_context *ctx_new=NULL; - struct db_trans *t; + struct db_context *ctx_new = NULL; struct db_prop *prop; - u_int trans_cnt; - int tn = 0; + u_int trans_cnt = esp_ealg_num * esp_aalg_num; if (!(policy & POLICY_ENCRYPT)) /* not possible, I think */ + { return NULL; - - trans_cnt = esp_ealg_num * esp_aalg_num; - DBG(DBG_EMITTING, - DBG_log("kernel_alg_db_prop_new() initial trans_cnt=%d" - , trans_cnt) - ) + } /* pass aprox. number of transforms and attributes */ ctx_new = db_prop_new(PROTO_IPSEC_ESP, trans_cnt, trans_cnt * 2); @@ -716,26 +710,7 @@ struct db_context* kernel_alg_db_new(struct alg_info_esp *alg_info, } } } - prop = db_prop_get(ctx_new); - - DBG(DBG_CONTROL|DBG_EMITTING, - DBG_log("kernel_alg_db_prop_new() " - "will return p_new->protoid=%d, p_new->trans_cnt=%d" - , prop->protoid, prop->trans_cnt) - ) - - for (t = prop->trans, tn = 0; tn < prop->trans_cnt; tn++) - { - DBG(DBG_CONTROL|DBG_EMITTING, - DBG_log("kernel_alg_db_prop_new() " - " trans[%d]: transid=%d, attr_cnt=%d, " - "attrs[0].type=%d, attrs[0].val=%d" - , tn - , t[tn].transid, t[tn].attr_cnt - , t[tn].attrs[0].type, t[tn].attrs[0].val) - ) - } return ctx_new; } diff --git a/src/pluto/keys.c b/src/pluto/keys.c index c494b8ba6..6dfbd6732 100644 --- a/src/pluto/keys.c +++ b/src/pluto/keys.c @@ -258,8 +258,8 @@ const chunk_t* get_preshared_secret(const struct connection *c) return s == NULL? NULL : &s->u.preshared_secret; } -/* check the existence of an RSA private key matching an RSA public - * key contained in an X.509 or OpenPGP certificate +/* check the existence of a private key matching a public key contained + * in an X.509 or OpenPGP certificate */ bool has_private_key(cert_t cert) { @@ -280,7 +280,7 @@ bool has_private_key(cert_t cert) } /* - * get the matching RSA private key belonging to a given X.509 certificate + * get the matching private key belonging to a given X.509 certificate */ private_key_t* get_x509_private_key(const x509cert_t *cert) { @@ -297,7 +297,7 @@ private_key_t* get_x509_private_key(const x509cert_t *cert) return NULL; } -/* find the appropriate RSA private key (see get_secret). +/* find the appropriate private key (see get_secret). * Failure is indicated by a NULL pointer. */ private_key_t* get_private_key(const struct connection *c) diff --git a/src/pluto/spdb.c b/src/pluto/spdb.c index 723124d0a..630c7f8b3 100644 --- a/src/pluto/spdb.c +++ b/src/pluto/spdb.c @@ -321,7 +321,7 @@ out_sa(pb_stream *outs alg_info_snprint(buf, sizeof (buf), (struct alg_info *)st->st_connection->alg_info_esp); - DBG_log(buf); + DBG_log("esp proposal: %s", buf); } ) db_ctx = kernel_alg_db_new(st->st_connection->alg_info_esp, st->st_policy); @@ -345,10 +345,10 @@ out_sa(pb_stream *outs alg_info_snprint(buf, sizeof (buf), (struct alg_info *)st->st_connection->alg_info_ike); - DBG_log(buf); + DBG_log("ike proposal: %s", buf); } ) - db_ctx = ike_alg_db_new(st->st_connection->alg_info_ike, st->st_policy); + db_ctx = ike_alg_db_new(st->st_connection, st->st_policy); p = db_prop_get(db_ctx); if (!p || p->trans_cnt == 0) @@ -794,7 +794,10 @@ parse_isakmp_policy(pb_stream *proposal_pbs *policy |= POLICY_PSK; break; case OAKLEY_RSA_SIG: - *policy |= POLICY_RSASIG; + case OAKLEY_ECDSA_256: + case OAKLEY_ECDSA_384: + case OAKLEY_ECDSA_512: + *policy |= POLICY_PUBKEY; break; case XAUTHInitPreShared: *policy |= POLICY_XAUTH_SERVER; @@ -978,7 +981,7 @@ parse_isakmp_sa_body(u_int32_t ipsecdoisit case OAKLEY_PRESHARED_KEY: if ((iap & POLICY_PSK) == LEMPTY) { - ugh = "policy does not allow OAKLEY_PRESHARED_KEY authentication"; + ugh = "policy does not allow pre-shared key authentication"; } else { @@ -1009,14 +1012,16 @@ parse_isakmp_sa_body(u_int32_t ipsecdoisit } break; case OAKLEY_RSA_SIG: - /* Accept if policy specifies RSASIG or is default */ - if ((iap & POLICY_RSASIG) == LEMPTY) + case OAKLEY_ECDSA_256: + case OAKLEY_ECDSA_384: + case OAKLEY_ECDSA_512: + if ((iap & POLICY_PUBKEY) == LEMPTY) { - ugh = "policy does not allow OAKLEY_RSA_SIG authentication"; + ugh = "policy does not allow public key authentication"; } else { - ta.auth = OAKLEY_RSA_SIG; + ta.auth = val; } break; case XAUTHInitRSA: diff --git a/src/starter/confread.c b/src/starter/confread.c index 97050ffc1..5fd2b9fbf 100644 --- a/src/starter/confread.c +++ b/src/starter/confread.c @@ -32,8 +32,8 @@ /* strings containing a colon are interpreted as an IPv6 address */ #define ip_version(string) (strchr(string, '.') ? AF_INET : AF_INET6) -static const char ike_defaults[] = "aes128-sha-modp2048"; -static const char esp_defaults[] = "aes128-sha1, 3des-md5"; +static const char ike_defaults[] = "aes128-sha1-modp2048,3des-sha1-modp1536"; +static const char esp_defaults[] = "aes128-sha1,3des-sha1"; static const char firewall_defaults[] = "ipsec _updown iptables"; @@ -70,7 +70,7 @@ static void default_values(starter_config_t *cfg) cfg->conn_default.seen = LEMPTY; cfg->conn_default.startup = STARTUP_NO; cfg->conn_default.state = STATE_IGNORE; - cfg->conn_default.policy = POLICY_ENCRYPT | POLICY_TUNNEL | POLICY_RSASIG | + cfg->conn_default.policy = POLICY_ENCRYPT | POLICY_TUNNEL | POLICY_PUBKEY | POLICY_PFS | POLICY_MOBIKE; cfg->conn_default.ike = clone_str(ike_defaults); @@ -555,18 +555,16 @@ load_conn(starter_conn_t *conn, kw_list_t *kw, starter_config_t *cfg) /* also handles the cases secret|rsasig and rsasig|secret */ for (;;) { - if (streq(value, "rsa") || streq(value, "rsasig")) + if (streq(value, "rsa") || streq(value, "rsasig") || + streq(value, "ecdsa") || streq(value, "ecdsasig") || + streq(value, "pubkey")) { - conn->policy |= POLICY_RSASIG | POLICY_ENCRYPT; + conn->policy |= POLICY_PUBKEY | POLICY_ENCRYPT; } else if (streq(value, "secret") || streq(value, "psk")) { conn->policy |= POLICY_PSK | POLICY_ENCRYPT; } - else if (streq(value, "ecdsa") || streq(value, "ecdsasig")) - { - conn->policy |= POLICY_ECDSASIG | POLICY_ENCRYPT; - } else if (streq(value, "xauthrsasig")) { conn->policy |= POLICY_XAUTH_RSASIG | POLICY_ENCRYPT; diff --git a/src/starter/starterstroke.c b/src/starter/starterstroke.c index 4e8f7f819..054e37fa7 100644 --- a/src/starter/starterstroke.c +++ b/src/starter/starterstroke.c @@ -239,7 +239,7 @@ int starter_stroke_add_conn(starter_config_t *cfg, starter_conn_t *conn) msg.add_conn.name = push_string(&msg, connection_name(conn)); /* PUBKEY is preferred to PSK and EAP */ - if (conn->policy & POLICY_RSASIG || conn->policy & POLICY_ECDSASIG) + if (conn->policy & POLICY_PUBKEY) { msg.add_conn.auth_method = AUTH_PUBKEY; } diff --git a/src/starter/starterwhack.c b/src/starter/starterwhack.c index 9e53cc76f..44b442ae2 100644 --- a/src/starter/starterwhack.c +++ b/src/starter/starterwhack.c @@ -323,7 +323,7 @@ starter_whack_add_conn(starter_conn_t *conn) r = send_whack_msg(&msg); - if (r == 0 && (conn->policy & POLICY_RSASIG)) + if (r == 0 && (conn->policy & POLICY_PUBKEY)) { r += starter_whack_add_pubkey (conn, &conn->left, "left"); r += starter_whack_add_pubkey (conn, &conn->right, "right"); diff --git a/src/whack/whack.c b/src/whack/whack.c index 4c3083bee..dd7f7721c 100644 --- a/src/whack/whack.c +++ b/src/whack/whack.c @@ -1634,8 +1634,8 @@ int main(int argc, char **argv) if (msg.policy & POLICY_OPPO) { - if ((msg.policy & (POLICY_PSK | POLICY_RSASIG)) != POLICY_RSASIG) - diag("only RSASIG is supported for opportunism"); + if ((msg.policy & (POLICY_PSK | POLICY_PUBKEY)) != POLICY_PUBKEY) + diag("only PUBKEY is supported for opportunism"); if ((msg.policy & POLICY_PFS) == 0) diag("PFS required for opportunism"); if ((msg.policy & POLICY_ENCRYPT) == 0) |