diff options
author | Angelos D. Keromytis <angelos@cvs.openbsd.org> | 2001-06-08 02:53:50 +0000 |
---|---|---|
committer | Angelos D. Keromytis <angelos@cvs.openbsd.org> | 2001-06-08 02:53:50 +0000 |
commit | 7a08f1b2c336f30da1050f456b147e5a07c9c4ce (patch) | |
tree | 7ceeaad09fc566da7ae5a44cbe1cf72f85417c54 | |
parent | 8621d107d75e99b1fec21b01df89f35e77a8cc92 (diff) |
Fork out some of the code in pfkeyv2.c to pfkeyv2_convert.c, to make
the former more managable/readable (an almost impossible task).
-rw-r--r-- | sys/net/pfkeyv2.c | 612 | ||||
-rw-r--r-- | sys/net/pfkeyv2.h | 31 | ||||
-rw-r--r-- | sys/net/pfkeyv2_convert.c | 684 |
3 files changed, 716 insertions, 611 deletions
diff --git a/sys/net/pfkeyv2.c b/sys/net/pfkeyv2.c index 9a593f8d663..829812bae68 100644 --- a/sys/net/pfkeyv2.c +++ b/sys/net/pfkeyv2.c @@ -1,4 +1,4 @@ -/* $OpenBSD: pfkeyv2.c,v 1.65 2001/06/07 05:27:52 angelos Exp $ */ +/* $OpenBSD: pfkeyv2.c,v 1.66 2001/06/08 02:53:49 angelos Exp $ */ /* * @(#)COPYRIGHT 1.1 (NRL) 17 January 1995 @@ -114,40 +114,9 @@ static struct sadb_alg aalgs[] = { SADB_AALG_RIPEMD160HMAC, 0, 160, 160 } }; -void export_address(void **, struct sockaddr *); -void export_identity(void **, struct tdb *, int); -void export_lifetime(void **, struct tdb *, int); -void export_credentials(void **, struct tdb *, int); -void export_sa(void **, struct tdb *); -void export_key(void **, struct tdb *, int); -void export_auth(void **, struct tdb *, int); - -void import_auth(struct tdb *, struct sadb_x_cred *, int); -void import_address(struct sockaddr *, struct sadb_address *); -void import_identity(struct tdb *, struct sadb_ident *, int); -void import_key(struct ipsecinit *, struct sadb_key *, int); -void import_lifetime(struct tdb *, struct sadb_lifetime *, int); -void import_credentials(struct tdb *, struct sadb_x_cred *, int); -void import_sa(struct tdb *, struct sadb_sa *, struct ipsecinit *); - -int pfkeyv2_create(struct socket *); -int pfkeyv2_get(struct tdb *, void **, void **); -int pfkeyv2_policy(struct ipsec_acquire *, void **, void **); -int pfkeyv2_release(struct socket *); -int pfkeyv2_send(struct socket *, void *, int); -int pfkeyv2_sendmessage(void **, int, struct socket *, u_int8_t, int); -int pfkeyv2_dump_walker(struct tdb *, void *, int); -int pfkeyv2_flush_walker(struct tdb *, void *, int); -int pfkeyv2_get_proto_alg(u_int8_t, u_int8_t *, int *); - -int pfdatatopacket(void *, int, struct mbuf **); - extern uint32_t sadb_exts_allowed_out[SADB_MAX+1]; extern uint32_t sadb_exts_required_out[SADB_MAX+1]; -#define EXTLEN(x) (((struct sadb_ext *)(x))->sadb_ext_len * sizeof(uint64_t)) -#define PADUP(x) (((x) + sizeof(uint64_t) - 1) & ~(sizeof(uint64_t) - 1)) - /* * Wrapper around m_devget(); copy data from contiguous buffer to mbuf * chain. @@ -216,585 +185,6 @@ pfkeyv2_release(struct socket *socket) } /* - * (Partly) Initialize a TDB based on an SADB_SA payload. Other parts - * of the TDB will be initialized by other import routines, and tdb_init(). - */ -void -import_sa(struct tdb *tdb, struct sadb_sa *sadb_sa, struct ipsecinit *ii) -{ - if (!sadb_sa) - return; - - if (ii) - { - ii->ii_encalg = sadb_sa->sadb_sa_encrypt; - ii->ii_authalg = sadb_sa->sadb_sa_auth; - - tdb->tdb_spi = sadb_sa->sadb_sa_spi; - tdb->tdb_wnd = sadb_sa->sadb_sa_replay; - - if (sadb_sa->sadb_sa_flags & SADB_SAFLAGS_PFS) - tdb->tdb_flags |= TDBF_PFS; - - if (sadb_sa->sadb_sa_flags & SADB_X_SAFLAGS_HALFIV) - tdb->tdb_flags |= TDBF_HALFIV; - - if (sadb_sa->sadb_sa_flags & SADB_X_SAFLAGS_TUNNEL) - tdb->tdb_flags |= TDBF_TUNNELING; - - if (sadb_sa->sadb_sa_flags & SADB_X_SAFLAGS_RANDOMPADDING) - tdb->tdb_flags |= TDBF_RANDOMPADDING; - - if (sadb_sa->sadb_sa_flags & SADB_X_SAFLAGS_NOREPLAY) - tdb->tdb_flags |= TDBF_NOREPLAY; - } - - if (sadb_sa->sadb_sa_state != SADB_SASTATE_MATURE) - tdb->tdb_flags |= TDBF_INVALID; -} - -/* - * Export some of the information on a TDB. - */ -void -export_sa(void **p, struct tdb *tdb) -{ - struct sadb_sa *sadb_sa = (struct sadb_sa *) *p; - - sadb_sa->sadb_sa_len = sizeof(struct sadb_sa) / sizeof(uint64_t); - - sadb_sa->sadb_sa_spi = tdb->tdb_spi; - sadb_sa->sadb_sa_replay = tdb->tdb_wnd; - - if (tdb->tdb_flags & TDBF_INVALID) - sadb_sa->sadb_sa_state = SADB_SASTATE_LARVAL; - - if (tdb->tdb_authalgxform) - { - switch (tdb->tdb_authalgxform->type) - { - case CRYPTO_MD5_HMAC: - sadb_sa->sadb_sa_auth = SADB_AALG_MD5HMAC; - break; - - case CRYPTO_SHA1_HMAC: - sadb_sa->sadb_sa_auth = SADB_AALG_SHA1HMAC; - break; - - case CRYPTO_RIPEMD160_HMAC: - sadb_sa->sadb_sa_auth = SADB_AALG_RIPEMD160HMAC; - break; - - case CRYPTO_MD5_KPDK: - sadb_sa->sadb_sa_auth = SADB_X_AALG_MD5; - break; - - case CRYPTO_SHA1_KPDK: - sadb_sa->sadb_sa_auth = SADB_X_AALG_SHA1; - break; - } - } - - if (tdb->tdb_encalgxform) - { - switch (tdb->tdb_encalgxform->type) - { - case CRYPTO_DES_CBC: - sadb_sa->sadb_sa_encrypt = SADB_EALG_DESCBC; - break; - - case CRYPTO_3DES_CBC: - sadb_sa->sadb_sa_encrypt = SADB_EALG_3DESCBC; - break; - - case CRYPTO_AES_CBC: - sadb_sa->sadb_sa_encrypt = SADB_X_EALG_AES; - break; - - case CRYPTO_CAST_CBC: - sadb_sa->sadb_sa_encrypt = SADB_X_EALG_CAST; - break; - - case CRYPTO_BLF_CBC: - sadb_sa->sadb_sa_encrypt = SADB_X_EALG_BLF; - break; - - case CRYPTO_SKIPJACK_CBC: - sadb_sa->sadb_sa_encrypt = SADB_X_EALG_SKIPJACK; - break; - } - } - - if (tdb->tdb_flags & TDBF_PFS) - sadb_sa->sadb_sa_flags |= SADB_SAFLAGS_PFS; - - /* Only relevant for the "old" IPsec transforms */ - if (tdb->tdb_flags & TDBF_HALFIV) - sadb_sa->sadb_sa_flags |= SADB_X_SAFLAGS_HALFIV; - - if (tdb->tdb_flags & TDBF_TUNNELING) - sadb_sa->sadb_sa_flags |= SADB_X_SAFLAGS_TUNNEL; - - if (tdb->tdb_flags & TDBF_RANDOMPADDING) - sadb_sa->sadb_sa_flags |= SADB_X_SAFLAGS_RANDOMPADDING; - - if (tdb->tdb_flags & TDBF_NOREPLAY) - sadb_sa->sadb_sa_flags |= SADB_X_SAFLAGS_NOREPLAY; - - *p += sizeof(struct sadb_sa); -} - -/* - * Initialize expirations and counters based on lifetime payload. - */ -void -import_lifetime(struct tdb *tdb, struct sadb_lifetime *sadb_lifetime, int type) -{ - if (!sadb_lifetime) - return; - - switch (type) - { - case PFKEYV2_LIFETIME_HARD: - if ((tdb->tdb_exp_allocations = - sadb_lifetime->sadb_lifetime_allocations) != 0) - tdb->tdb_flags |= TDBF_ALLOCATIONS; - else - tdb->tdb_flags &= ~TDBF_ALLOCATIONS; - - if ((tdb->tdb_exp_bytes = sadb_lifetime->sadb_lifetime_bytes) != 0) - tdb->tdb_flags |= TDBF_BYTES; - else - tdb->tdb_flags &= ~TDBF_BYTES; - - if ((tdb->tdb_exp_timeout = - sadb_lifetime->sadb_lifetime_addtime) != 0) - { - tdb->tdb_flags |= TDBF_TIMER; - timeout_add(&tdb->tdb_timer_tmo, hz * tdb->tdb_exp_timeout); - } else - tdb->tdb_flags &= ~TDBF_TIMER; - - if ((tdb->tdb_exp_first_use = - sadb_lifetime->sadb_lifetime_usetime) != 0) - { - tdb->tdb_flags |= TDBF_FIRSTUSE; - timeout_add(&tdb->tdb_first_tmo, hz * tdb->tdb_exp_first_use); - } - else - tdb->tdb_flags &= ~TDBF_FIRSTUSE; - break; - - case PFKEYV2_LIFETIME_SOFT: - if ((tdb->tdb_soft_allocations = - sadb_lifetime->sadb_lifetime_allocations) != 0) - tdb->tdb_flags |= TDBF_SOFT_ALLOCATIONS; - else - tdb->tdb_flags &= ~TDBF_SOFT_ALLOCATIONS; - - if ((tdb->tdb_soft_bytes = - sadb_lifetime->sadb_lifetime_bytes) != 0) - tdb->tdb_flags |= TDBF_SOFT_BYTES; - else - tdb->tdb_flags &= ~TDBF_SOFT_BYTES; - - if ((tdb->tdb_soft_timeout = - sadb_lifetime->sadb_lifetime_addtime) != 0) - { - tdb->tdb_flags |= TDBF_SOFT_TIMER; - timeout_add(&tdb->tdb_stimer_tmo, hz * tdb->tdb_soft_timeout); - } - else - tdb->tdb_flags &= ~TDBF_SOFT_TIMER; - - if ((tdb->tdb_soft_first_use = - sadb_lifetime->sadb_lifetime_usetime) != 0) - { - tdb->tdb_flags |= TDBF_SOFT_FIRSTUSE; - timeout_add(&tdb->tdb_sfirst_tmo, hz * tdb->tdb_soft_first_use); - } - else - tdb->tdb_flags &= ~TDBF_SOFT_FIRSTUSE; - break; - - case PFKEYV2_LIFETIME_CURRENT: /* Nothing fancy here */ - tdb->tdb_cur_allocations = - sadb_lifetime->sadb_lifetime_allocations; - tdb->tdb_cur_bytes = sadb_lifetime->sadb_lifetime_bytes; - tdb->tdb_established = sadb_lifetime->sadb_lifetime_addtime; - tdb->tdb_first_use = sadb_lifetime->sadb_lifetime_usetime; - } -} - -/* - * Export TDB expiration information. - */ -void -export_lifetime(void **p, struct tdb *tdb, int type) -{ - struct sadb_lifetime *sadb_lifetime = (struct sadb_lifetime *) *p; - - sadb_lifetime->sadb_lifetime_len = sizeof(struct sadb_lifetime) / - sizeof(uint64_t); - - switch (type) - { - case PFKEYV2_LIFETIME_HARD: - if (tdb->tdb_flags & TDBF_ALLOCATIONS) - sadb_lifetime->sadb_lifetime_allocations = - tdb->tdb_exp_allocations; - - if (tdb->tdb_flags & TDBF_BYTES) - sadb_lifetime->sadb_lifetime_bytes = tdb->tdb_exp_bytes; - - if (tdb->tdb_flags & TDBF_TIMER) - sadb_lifetime->sadb_lifetime_addtime = tdb->tdb_exp_timeout; - - if (tdb->tdb_flags & TDBF_FIRSTUSE) - sadb_lifetime->sadb_lifetime_usetime = tdb->tdb_exp_first_use; - break; - - case PFKEYV2_LIFETIME_SOFT: - if (tdb->tdb_flags & TDBF_SOFT_ALLOCATIONS) - sadb_lifetime->sadb_lifetime_allocations = - tdb->tdb_soft_allocations; - - if (tdb->tdb_flags & TDBF_SOFT_BYTES) - sadb_lifetime->sadb_lifetime_bytes = tdb->tdb_soft_bytes; - - if (tdb->tdb_flags & TDBF_SOFT_TIMER) - sadb_lifetime->sadb_lifetime_addtime = tdb->tdb_soft_timeout; - - if (tdb->tdb_flags & TDBF_SOFT_FIRSTUSE) - sadb_lifetime->sadb_lifetime_usetime = tdb->tdb_soft_first_use; - break; - - case PFKEYV2_LIFETIME_CURRENT: - sadb_lifetime->sadb_lifetime_allocations = - tdb->tdb_cur_allocations; - sadb_lifetime->sadb_lifetime_bytes = tdb->tdb_cur_bytes; - sadb_lifetime->sadb_lifetime_addtime = tdb->tdb_established; - sadb_lifetime->sadb_lifetime_usetime = tdb->tdb_first_use; - break; - } - - *p += sizeof(struct sadb_lifetime); -} - -/* - * Copy an SADB_ADDRESS payload to a struct sockaddr. - */ -void -import_address(struct sockaddr *sa, struct sadb_address *sadb_address) -{ - int salen; - struct sockaddr *ssa = (struct sockaddr *)((void *) sadb_address + - sizeof(struct sadb_address)); - - if (!sadb_address) - return; - - if (ssa->sa_len) - salen = ssa->sa_len; - else - switch(ssa->sa_family) - { -#ifdef INET - case AF_INET: - salen = sizeof(struct sockaddr_in); - break; -#endif /* INET */ - -#if INET6 - case AF_INET6: - salen = sizeof(struct sockaddr_in6); - break; -#endif /* INET6 */ - - default: - return; - } - - bcopy(ssa, sa, salen); - sa->sa_len = salen; -} - -/* - * Export a struct sockaddr as an SADB_ADDRESS payload. - */ -void -export_address(void **p, struct sockaddr *sa) -{ - struct sadb_address *sadb_address = (struct sadb_address *) *p; - - sadb_address->sadb_address_len = (sizeof(struct sadb_address) + - PADUP(SA_LEN(sa))) / sizeof(uint64_t); - - *p += sizeof(struct sadb_address); - bcopy(sa, *p, SA_LEN(sa)); - ((struct sockaddr *) *p)->sa_family = sa->sa_family; - *p += PADUP(SA_LEN(sa)); -} - -/* - * Import authentication information into the TDB. - */ -void -import_auth(struct tdb *tdb, struct sadb_x_cred *sadb_auth, int dstauth) -{ - struct ipsec_ref **ipr; - - if (!sadb_auth) - return; - - if (dstauth == PFKEYV2_AUTH_REMOTE) - ipr = &tdb->tdb_remote_auth; - else - ipr = &tdb->tdb_local_auth; - - MALLOC(*ipr, struct ipsec_ref *, EXTLEN(sadb_auth) - - sizeof(struct sadb_x_cred) + sizeof(struct ipsec_ref), - M_CREDENTIALS, M_WAITOK); - (*ipr)->ref_len = EXTLEN(sadb_auth) - sizeof(struct sadb_x_cred); - switch (sadb_auth->sadb_x_cred_type) - { - case SADB_X_AUTHTYPE_PASSPHRASE: - (*ipr)->ref_type = IPSP_AUTH_PASSPHRASE; - break; - case SADB_X_AUTHTYPE_RSA: - (*ipr)->ref_type = IPSP_AUTH_RSA; - break; - default: - FREE(*ipr, M_CREDENTIALS); - *ipr = NULL; - return; - } - (*ipr)->ref_count = 1; - (*ipr)->ref_malloctype = M_CREDENTIALS; - bcopy((void *) sadb_auth + sizeof(struct sadb_x_cred), - (*ipr) + 1, (*ipr)->ref_len); -} - -/* - * Import a set of credentials into the TDB. - */ -void -import_credentials(struct tdb *tdb, struct sadb_x_cred *sadb_cred, int dstcred) -{ - struct ipsec_ref **ipr; - - if (!sadb_cred) - return; - - if (dstcred == PFKEYV2_CRED_REMOTE) - ipr = &tdb->tdb_remote_cred; - else - ipr = &tdb->tdb_local_cred; - - MALLOC(*ipr, struct ipsec_ref *, EXTLEN(sadb_cred) - - sizeof(struct sadb_x_cred) + sizeof(struct ipsec_ref), - M_CREDENTIALS, M_WAITOK); - (*ipr)->ref_len = EXTLEN(sadb_cred) - sizeof(struct sadb_x_cred); - switch (sadb_cred->sadb_x_cred_type) - { - case SADB_X_CREDTYPE_X509: - (*ipr)->ref_type = IPSP_CRED_X509; - break; - case SADB_X_CREDTYPE_KEYNOTE: - (*ipr)->ref_type = IPSP_CRED_KEYNOTE; - break; - default: - FREE(*ipr, M_CREDENTIALS); - *ipr = NULL; - return; - } - (*ipr)->ref_count = 1; - (*ipr)->ref_malloctype = M_CREDENTIALS; - bcopy((void *) sadb_cred + sizeof(struct sadb_x_cred), - (*ipr) + 1, (*ipr)->ref_len); -} - -/* - * Import an identity payload into the TDB. - */ -void -import_identity(struct tdb *tdb, struct sadb_ident *sadb_ident, int type) -{ - struct ipsec_ref **ipr; - - if (!sadb_ident) - return; - - if (type == PFKEYV2_IDENTITY_SRC) - ipr = &tdb->tdb_srcid; - else - ipr = &tdb->tdb_dstid; - - MALLOC(*ipr, struct ipsec_ref *, EXTLEN(sadb_ident) - - sizeof(struct sadb_ident) + sizeof(struct ipsec_ref), M_CREDENTIALS, - M_WAITOK); - (*ipr)->ref_len = EXTLEN(sadb_ident) - sizeof(struct sadb_ident); - switch (sadb_ident->sadb_ident_type) - { - case SADB_IDENTTYPE_PREFIX: - (*ipr)->ref_type = IPSP_IDENTITY_PREFIX; - break; - case SADB_IDENTTYPE_FQDN: - (*ipr)->ref_type = IPSP_IDENTITY_FQDN; - break; - case SADB_IDENTTYPE_USERFQDN: - (*ipr)->ref_type = IPSP_IDENTITY_USERFQDN; - break; - case SADB_X_IDENTTYPE_CONNECTION: - (*ipr)->ref_type = IPSP_IDENTITY_CONNECTION; - break; - default: - FREE(*ipr, M_CREDENTIALS); - *ipr = NULL; - return; - } - (*ipr)->ref_count = 1; - (*ipr)->ref_malloctype = M_CREDENTIALS; - bcopy((void *) sadb_ident + sizeof(struct sadb_ident), (*ipr) + 1, - (*ipr)->ref_len); -} - -void -export_credentials(void **p, struct tdb *tdb, int dstcred) -{ - struct ipsec_ref **ipr; - struct sadb_x_cred *sadb_cred = (struct sadb_x_cred *) *p; - - if (dstcred == PFKEYV2_CRED_REMOTE) - ipr = &tdb->tdb_remote_cred; - else - ipr = &tdb->tdb_local_cred; - - sadb_cred->sadb_x_cred_len = (sizeof(struct sadb_x_cred) + - PADUP((*ipr)->ref_len)) / sizeof(uint64_t); - - switch ((*ipr)->ref_type) - { - case IPSP_CRED_KEYNOTE: - sadb_cred->sadb_x_cred_type = SADB_X_CREDTYPE_KEYNOTE; - break; - case IPSP_CRED_X509: - sadb_cred->sadb_x_cred_type = SADB_X_CREDTYPE_X509; - break; - } - *p += sizeof(struct sadb_x_cred); - bcopy((*ipr) + 1, *p, (*ipr)->ref_len); - *p += PADUP((*ipr)->ref_len); -} - -void -export_auth(void **p, struct tdb *tdb, int dstauth) -{ - struct ipsec_ref **ipr; - struct sadb_x_cred *sadb_auth = (struct sadb_x_cred *) *p; - - if (dstauth == PFKEYV2_AUTH_REMOTE) - ipr = &tdb->tdb_remote_auth; - else - ipr = &tdb->tdb_local_auth; - - sadb_auth->sadb_x_cred_len = (sizeof(struct sadb_x_cred) + - PADUP((*ipr)->ref_len)) / sizeof(uint64_t); - - switch ((*ipr)->ref_type) - { - case IPSP_CRED_KEYNOTE: - sadb_auth->sadb_x_cred_type = SADB_X_CREDTYPE_KEYNOTE; - break; - case IPSP_CRED_X509: - sadb_auth->sadb_x_cred_type = SADB_X_CREDTYPE_X509; - break; - } - *p += sizeof(struct sadb_x_cred); - bcopy((*ipr) + 1, *p, (*ipr)->ref_len); - *p += PADUP((*ipr)->ref_len); -} - -void -export_identity(void **p, struct tdb *tdb, int type) -{ - struct ipsec_ref **ipr; - struct sadb_ident *sadb_ident = (struct sadb_ident *) *p; - - if (type == PFKEYV2_IDENTITY_SRC) - ipr = &tdb->tdb_srcid; - else - ipr = &tdb->tdb_dstid; - - sadb_ident->sadb_ident_len = (sizeof(struct sadb_ident) + - PADUP((*ipr)->ref_len)) / sizeof(uint64_t); - switch ((*ipr)->ref_type) - { - case IPSP_IDENTITY_PREFIX: - sadb_ident->sadb_ident_type = SADB_IDENTTYPE_PREFIX; - break; - case IPSP_IDENTITY_FQDN: - sadb_ident->sadb_ident_type = SADB_IDENTTYPE_FQDN; - break; - case IPSP_IDENTITY_USERFQDN: - sadb_ident->sadb_ident_type = SADB_IDENTTYPE_USERFQDN; - break; - case IPSP_IDENTITY_CONNECTION: - sadb_ident->sadb_ident_type = SADB_X_IDENTTYPE_CONNECTION; - break; - } - *p += sizeof(struct sadb_ident); - bcopy((*ipr) + 1, *p, (*ipr)->ref_len); - *p += PADUP((*ipr)->ref_len); -} - -/* ... */ -void -import_key(struct ipsecinit *ii, struct sadb_key *sadb_key, int type) -{ - if (!sadb_key) - return; - - if (type == PFKEYV2_ENCRYPTION_KEY) - { /* Encryption key */ - ii->ii_enckeylen = sadb_key->sadb_key_bits / 8; - ii->ii_enckey = (void *)sadb_key + sizeof(struct sadb_key); - } - else - { - ii->ii_authkeylen = sadb_key->sadb_key_bits / 8; - ii->ii_authkey = (void *)sadb_key + sizeof(struct sadb_key); - } -} - -void -export_key(void **p, struct tdb *tdb, int type) -{ - struct sadb_key *sadb_key = (struct sadb_key *) *p; - - if (type == PFKEYV2_ENCRYPTION_KEY) - { - sadb_key->sadb_key_len = (sizeof(struct sadb_key) + - PADUP(tdb->tdb_emxkeylen)) / - sizeof(uint64_t); - sadb_key->sadb_key_bits = tdb->tdb_emxkeylen * 8; - *p += sizeof(struct sadb_key); - bcopy(tdb->tdb_emxkey, *p, tdb->tdb_emxkeylen); - *p += PADUP(tdb->tdb_emxkeylen); - } - else - { - sadb_key->sadb_key_len = (sizeof(struct sadb_key) + - PADUP(tdb->tdb_amxkeylen)) / - sizeof(uint64_t); - sadb_key->sadb_key_bits = tdb->tdb_amxkeylen * 8; - *p += sizeof(struct sadb_key); - bcopy(tdb->tdb_amxkey, *p, tdb->tdb_amxkeylen); - *p += PADUP(tdb->tdb_amxkeylen); - } -} - -/* * Send a PFKEYv2 message, possibly to many receivers, based on the * satype of the socket (which is set by the REGISTER message), and the * third argument. diff --git a/sys/net/pfkeyv2.h b/sys/net/pfkeyv2.h index 371714dc037..d4fe2586c15 100644 --- a/sys/net/pfkeyv2.h +++ b/sys/net/pfkeyv2.h @@ -323,6 +323,9 @@ struct tdb; struct socket; struct mbuf; +#define EXTLEN(x) (((struct sadb_ext *)(x))->sadb_ext_len * sizeof(uint64_t)) +#define PADUP(x) (((x) + sizeof(uint64_t) - 1) & ~(sizeof(uint64_t) - 1)) + struct pfkey_version { int protocol; @@ -357,5 +360,33 @@ int pfkeyv2_acquire(struct ipsec_policy *, union sockaddr_union *, int pfkey_register(struct pfkey_version *version); int pfkey_unregister(struct pfkey_version *version); int pfkey_sendup(struct socket *socket, struct mbuf *packet, int more); + +int pfkeyv2_create(struct socket *); +int pfkeyv2_get(struct tdb *, void **, void **); +int pfkeyv2_policy(struct ipsec_acquire *, void **, void **); +int pfkeyv2_release(struct socket *); +int pfkeyv2_send(struct socket *, void *, int); +int pfkeyv2_sendmessage(void **, int, struct socket *, u_int8_t, int); +int pfkeyv2_dump_walker(struct tdb *, void *, int); +int pfkeyv2_flush_walker(struct tdb *, void *, int); +int pfkeyv2_get_proto_alg(u_int8_t, u_int8_t *, int *); + +int pfdatatopacket(void *, int, struct mbuf **); + +void export_address(void **, struct sockaddr *); +void export_identity(void **, struct tdb *, int); +void export_lifetime(void **, struct tdb *, int); +void export_credentials(void **, struct tdb *, int); +void export_sa(void **, struct tdb *); +void export_key(void **, struct tdb *, int); +void export_auth(void **, struct tdb *, int); + +void import_auth(struct tdb *, struct sadb_x_cred *, int); +void import_address(struct sockaddr *, struct sadb_address *); +void import_identity(struct tdb *, struct sadb_ident *, int); +void import_key(struct ipsecinit *, struct sadb_key *, int); +void import_lifetime(struct tdb *, struct sadb_lifetime *, int); +void import_credentials(struct tdb *, struct sadb_x_cred *, int); +void import_sa(struct tdb *, struct sadb_sa *, struct ipsecinit *); #endif /* _KERNEL */ #endif /* _NET_PFKEY_V2_H */ diff --git a/sys/net/pfkeyv2_convert.c b/sys/net/pfkeyv2_convert.c new file mode 100644 index 00000000000..b6fd5cf7a76 --- /dev/null +++ b/sys/net/pfkeyv2_convert.c @@ -0,0 +1,684 @@ +/* $OpenBSD: pfkeyv2_convert.c,v 1.1 2001/06/08 02:53:49 angelos Exp $ */ + +/* + * The author of this code is Angelos D. Keromytis (angelos@keromytis.org) + * + * Part of this code is based on code written by Craig Metz (cmetz@inner.net) + * for NRL. Those licenses follow this one. + * + * Copyright (c) 2001 Angelos D. Keromytis. + * + * Permission to use, copy, and modify this software without fee + * is hereby granted, provided that this entire notice is included in + * all copies of any software which is or includes a copy or + * modification of this software. + * You may use this code under the GNU public license if you so wish. Please + * contribute changes back to the authors under this freer than GPL license + * so that we may further the use of strong encryption without limitations to + * all. + * + * THIS SOFTWARE IS BEING PROVIDED "AS IS", WITHOUT ANY EXPRESS OR + * IMPLIED WARRANTY. IN PARTICULAR, NONE OF THE AUTHORS MAKES ANY + * REPRESENTATION OR WARRANTY OF ANY KIND CONCERNING THE + * MERCHANTABILITY OF THIS SOFTWARE OR ITS FITNESS FOR ANY PARTICULAR + * PURPOSE. + */ + +/* + * @(#)COPYRIGHT 1.1 (NRL) 17 January 1995 + * + * NRL grants permission for redistribution and use in source and binary + * forms, with or without modification, of the software and documentation + * created at NRL provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgements: + * This product includes software developed by the University of + * California, Berkeley and its contributors. + * This product includes software developed at the Information + * Technology Division, US Naval Research Laboratory. + * 4. Neither the name of the NRL nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THE SOFTWARE PROVIDED BY NRL IS PROVIDED BY NRL AND CONTRIBUTORS ``AS + * IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED + * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A + * PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL NRL OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF + * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * The views and conclusions contained in the software and documentation + * are those of the authors and should not be interpreted as representing + * official policies, either expressed or implied, of the US Naval + * Research Laboratory (NRL). + */ + +/* + * Copyright (c) 1995, 1996, 1997, 1998, 1999 Craig Metz. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. Neither the name of the author nor the names of any contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +#include <sys/types.h> +#include <sys/param.h> +#include <sys/systm.h> +#include <sys/mbuf.h> +#include <sys/kernel.h> +#include <sys/socket.h> +#include <netinet/ip_ipsp.h> +#include <net/pfkeyv2.h> +#include <crypto/crypto.h> +#include <crypto/xform.h> + +/* + * (Partly) Initialize a TDB based on an SADB_SA payload. Other parts + * of the TDB will be initialized by other import routines, and tdb_init(). + */ +void +import_sa(struct tdb *tdb, struct sadb_sa *sadb_sa, struct ipsecinit *ii) +{ + if (!sadb_sa) + return; + + if (ii) + { + ii->ii_encalg = sadb_sa->sadb_sa_encrypt; + ii->ii_authalg = sadb_sa->sadb_sa_auth; + + tdb->tdb_spi = sadb_sa->sadb_sa_spi; + tdb->tdb_wnd = sadb_sa->sadb_sa_replay; + + if (sadb_sa->sadb_sa_flags & SADB_SAFLAGS_PFS) + tdb->tdb_flags |= TDBF_PFS; + + if (sadb_sa->sadb_sa_flags & SADB_X_SAFLAGS_HALFIV) + tdb->tdb_flags |= TDBF_HALFIV; + + if (sadb_sa->sadb_sa_flags & SADB_X_SAFLAGS_TUNNEL) + tdb->tdb_flags |= TDBF_TUNNELING; + + if (sadb_sa->sadb_sa_flags & SADB_X_SAFLAGS_RANDOMPADDING) + tdb->tdb_flags |= TDBF_RANDOMPADDING; + + if (sadb_sa->sadb_sa_flags & SADB_X_SAFLAGS_NOREPLAY) + tdb->tdb_flags |= TDBF_NOREPLAY; + } + + if (sadb_sa->sadb_sa_state != SADB_SASTATE_MATURE) + tdb->tdb_flags |= TDBF_INVALID; +} + +/* + * Export some of the information on a TDB. + */ +void +export_sa(void **p, struct tdb *tdb) +{ + struct sadb_sa *sadb_sa = (struct sadb_sa *) *p; + + sadb_sa->sadb_sa_len = sizeof(struct sadb_sa) / sizeof(uint64_t); + + sadb_sa->sadb_sa_spi = tdb->tdb_spi; + sadb_sa->sadb_sa_replay = tdb->tdb_wnd; + + if (tdb->tdb_flags & TDBF_INVALID) + sadb_sa->sadb_sa_state = SADB_SASTATE_LARVAL; + + if (tdb->tdb_authalgxform) + { + switch (tdb->tdb_authalgxform->type) + { + case CRYPTO_MD5_HMAC: + sadb_sa->sadb_sa_auth = SADB_AALG_MD5HMAC; + break; + + case CRYPTO_SHA1_HMAC: + sadb_sa->sadb_sa_auth = SADB_AALG_SHA1HMAC; + break; + + case CRYPTO_RIPEMD160_HMAC: + sadb_sa->sadb_sa_auth = SADB_AALG_RIPEMD160HMAC; + break; + + case CRYPTO_MD5_KPDK: + sadb_sa->sadb_sa_auth = SADB_X_AALG_MD5; + break; + + case CRYPTO_SHA1_KPDK: + sadb_sa->sadb_sa_auth = SADB_X_AALG_SHA1; + break; + } + } + + if (tdb->tdb_encalgxform) + { + switch (tdb->tdb_encalgxform->type) + { + case CRYPTO_DES_CBC: + sadb_sa->sadb_sa_encrypt = SADB_EALG_DESCBC; + break; + + case CRYPTO_3DES_CBC: + sadb_sa->sadb_sa_encrypt = SADB_EALG_3DESCBC; + break; + + case CRYPTO_AES_CBC: + sadb_sa->sadb_sa_encrypt = SADB_X_EALG_AES; + break; + + case CRYPTO_CAST_CBC: + sadb_sa->sadb_sa_encrypt = SADB_X_EALG_CAST; + break; + + case CRYPTO_BLF_CBC: + sadb_sa->sadb_sa_encrypt = SADB_X_EALG_BLF; + break; + + case CRYPTO_SKIPJACK_CBC: + sadb_sa->sadb_sa_encrypt = SADB_X_EALG_SKIPJACK; + break; + } + } + + if (tdb->tdb_flags & TDBF_PFS) + sadb_sa->sadb_sa_flags |= SADB_SAFLAGS_PFS; + + /* Only relevant for the "old" IPsec transforms */ + if (tdb->tdb_flags & TDBF_HALFIV) + sadb_sa->sadb_sa_flags |= SADB_X_SAFLAGS_HALFIV; + + if (tdb->tdb_flags & TDBF_TUNNELING) + sadb_sa->sadb_sa_flags |= SADB_X_SAFLAGS_TUNNEL; + + if (tdb->tdb_flags & TDBF_RANDOMPADDING) + sadb_sa->sadb_sa_flags |= SADB_X_SAFLAGS_RANDOMPADDING; + + if (tdb->tdb_flags & TDBF_NOREPLAY) + sadb_sa->sadb_sa_flags |= SADB_X_SAFLAGS_NOREPLAY; + + *p += sizeof(struct sadb_sa); +} + +/* + * Initialize expirations and counters based on lifetime payload. + */ +void +import_lifetime(struct tdb *tdb, struct sadb_lifetime *sadb_lifetime, int type) +{ + if (!sadb_lifetime) + return; + + switch (type) + { + case PFKEYV2_LIFETIME_HARD: + if ((tdb->tdb_exp_allocations = + sadb_lifetime->sadb_lifetime_allocations) != 0) + tdb->tdb_flags |= TDBF_ALLOCATIONS; + else + tdb->tdb_flags &= ~TDBF_ALLOCATIONS; + + if ((tdb->tdb_exp_bytes = sadb_lifetime->sadb_lifetime_bytes) != 0) + tdb->tdb_flags |= TDBF_BYTES; + else + tdb->tdb_flags &= ~TDBF_BYTES; + + if ((tdb->tdb_exp_timeout = + sadb_lifetime->sadb_lifetime_addtime) != 0) + { + tdb->tdb_flags |= TDBF_TIMER; + timeout_add(&tdb->tdb_timer_tmo, hz * tdb->tdb_exp_timeout); + } else + tdb->tdb_flags &= ~TDBF_TIMER; + + if ((tdb->tdb_exp_first_use = + sadb_lifetime->sadb_lifetime_usetime) != 0) + { + tdb->tdb_flags |= TDBF_FIRSTUSE; + timeout_add(&tdb->tdb_first_tmo, hz * tdb->tdb_exp_first_use); + } + else + tdb->tdb_flags &= ~TDBF_FIRSTUSE; + break; + + case PFKEYV2_LIFETIME_SOFT: + if ((tdb->tdb_soft_allocations = + sadb_lifetime->sadb_lifetime_allocations) != 0) + tdb->tdb_flags |= TDBF_SOFT_ALLOCATIONS; + else + tdb->tdb_flags &= ~TDBF_SOFT_ALLOCATIONS; + + if ((tdb->tdb_soft_bytes = + sadb_lifetime->sadb_lifetime_bytes) != 0) + tdb->tdb_flags |= TDBF_SOFT_BYTES; + else + tdb->tdb_flags &= ~TDBF_SOFT_BYTES; + + if ((tdb->tdb_soft_timeout = + sadb_lifetime->sadb_lifetime_addtime) != 0) + { + tdb->tdb_flags |= TDBF_SOFT_TIMER; + timeout_add(&tdb->tdb_stimer_tmo, hz * tdb->tdb_soft_timeout); + } + else + tdb->tdb_flags &= ~TDBF_SOFT_TIMER; + + if ((tdb->tdb_soft_first_use = + sadb_lifetime->sadb_lifetime_usetime) != 0) + { + tdb->tdb_flags |= TDBF_SOFT_FIRSTUSE; + timeout_add(&tdb->tdb_sfirst_tmo, hz * + tdb->tdb_soft_first_use); + } + else + tdb->tdb_flags &= ~TDBF_SOFT_FIRSTUSE; + break; + + case PFKEYV2_LIFETIME_CURRENT: /* Nothing fancy here */ + tdb->tdb_cur_allocations = + sadb_lifetime->sadb_lifetime_allocations; + tdb->tdb_cur_bytes = sadb_lifetime->sadb_lifetime_bytes; + tdb->tdb_established = sadb_lifetime->sadb_lifetime_addtime; + tdb->tdb_first_use = sadb_lifetime->sadb_lifetime_usetime; + } +} + +/* + * Export TDB expiration information. + */ +void +export_lifetime(void **p, struct tdb *tdb, int type) +{ + struct sadb_lifetime *sadb_lifetime = (struct sadb_lifetime *) *p; + + sadb_lifetime->sadb_lifetime_len = sizeof(struct sadb_lifetime) / + sizeof(uint64_t); + + switch (type) + { + case PFKEYV2_LIFETIME_HARD: + if (tdb->tdb_flags & TDBF_ALLOCATIONS) + sadb_lifetime->sadb_lifetime_allocations = + tdb->tdb_exp_allocations; + + if (tdb->tdb_flags & TDBF_BYTES) + sadb_lifetime->sadb_lifetime_bytes = tdb->tdb_exp_bytes; + + if (tdb->tdb_flags & TDBF_TIMER) + sadb_lifetime->sadb_lifetime_addtime = tdb->tdb_exp_timeout; + + if (tdb->tdb_flags & TDBF_FIRSTUSE) + sadb_lifetime->sadb_lifetime_usetime = tdb->tdb_exp_first_use; + break; + + case PFKEYV2_LIFETIME_SOFT: + if (tdb->tdb_flags & TDBF_SOFT_ALLOCATIONS) + sadb_lifetime->sadb_lifetime_allocations = + tdb->tdb_soft_allocations; + + if (tdb->tdb_flags & TDBF_SOFT_BYTES) + sadb_lifetime->sadb_lifetime_bytes = tdb->tdb_soft_bytes; + + if (tdb->tdb_flags & TDBF_SOFT_TIMER) + sadb_lifetime->sadb_lifetime_addtime = tdb->tdb_soft_timeout; + + if (tdb->tdb_flags & TDBF_SOFT_FIRSTUSE) + sadb_lifetime->sadb_lifetime_usetime = tdb->tdb_soft_first_use; + break; + + case PFKEYV2_LIFETIME_CURRENT: + sadb_lifetime->sadb_lifetime_allocations = + tdb->tdb_cur_allocations; + sadb_lifetime->sadb_lifetime_bytes = tdb->tdb_cur_bytes; + sadb_lifetime->sadb_lifetime_addtime = tdb->tdb_established; + sadb_lifetime->sadb_lifetime_usetime = tdb->tdb_first_use; + break; + } + + *p += sizeof(struct sadb_lifetime); +} + +/* + * Copy an SADB_ADDRESS payload to a struct sockaddr. + */ +void +import_address(struct sockaddr *sa, struct sadb_address *sadb_address) +{ + int salen; + struct sockaddr *ssa = (struct sockaddr *)((void *) sadb_address + + sizeof(struct sadb_address)); + + if (!sadb_address) + return; + + if (ssa->sa_len) + salen = ssa->sa_len; + else + switch(ssa->sa_family) + { +#ifdef INET + case AF_INET: + salen = sizeof(struct sockaddr_in); + break; +#endif /* INET */ + +#if INET6 + case AF_INET6: + salen = sizeof(struct sockaddr_in6); + break; +#endif /* INET6 */ + + default: + return; + } + + bcopy(ssa, sa, salen); + sa->sa_len = salen; +} + +/* + * Export a struct sockaddr as an SADB_ADDRESS payload. + */ +void +export_address(void **p, struct sockaddr *sa) +{ + struct sadb_address *sadb_address = (struct sadb_address *) *p; + + sadb_address->sadb_address_len = (sizeof(struct sadb_address) + + PADUP(SA_LEN(sa))) / sizeof(uint64_t); + + *p += sizeof(struct sadb_address); + bcopy(sa, *p, SA_LEN(sa)); + ((struct sockaddr *) *p)->sa_family = sa->sa_family; + *p += PADUP(SA_LEN(sa)); +} + +/* + * Import authentication information into the TDB. + */ +void +import_auth(struct tdb *tdb, struct sadb_x_cred *sadb_auth, int dstauth) +{ + struct ipsec_ref **ipr; + + if (!sadb_auth) + return; + + if (dstauth == PFKEYV2_AUTH_REMOTE) + ipr = &tdb->tdb_remote_auth; + else + ipr = &tdb->tdb_local_auth; + + MALLOC(*ipr, struct ipsec_ref *, EXTLEN(sadb_auth) - + sizeof(struct sadb_x_cred) + sizeof(struct ipsec_ref), + M_CREDENTIALS, M_WAITOK); + (*ipr)->ref_len = EXTLEN(sadb_auth) - sizeof(struct sadb_x_cred); + switch (sadb_auth->sadb_x_cred_type) + { + case SADB_X_AUTHTYPE_PASSPHRASE: + (*ipr)->ref_type = IPSP_AUTH_PASSPHRASE; + break; + case SADB_X_AUTHTYPE_RSA: + (*ipr)->ref_type = IPSP_AUTH_RSA; + break; + default: + FREE(*ipr, M_CREDENTIALS); + *ipr = NULL; + return; + } + (*ipr)->ref_count = 1; + (*ipr)->ref_malloctype = M_CREDENTIALS; + bcopy((void *) sadb_auth + sizeof(struct sadb_x_cred), + (*ipr) + 1, (*ipr)->ref_len); +} + +/* + * Import a set of credentials into the TDB. + */ +void +import_credentials(struct tdb *tdb, struct sadb_x_cred *sadb_cred, int dstcred) +{ + struct ipsec_ref **ipr; + + if (!sadb_cred) + return; + + if (dstcred == PFKEYV2_CRED_REMOTE) + ipr = &tdb->tdb_remote_cred; + else + ipr = &tdb->tdb_local_cred; + + MALLOC(*ipr, struct ipsec_ref *, EXTLEN(sadb_cred) - + sizeof(struct sadb_x_cred) + sizeof(struct ipsec_ref), + M_CREDENTIALS, M_WAITOK); + (*ipr)->ref_len = EXTLEN(sadb_cred) - sizeof(struct sadb_x_cred); + switch (sadb_cred->sadb_x_cred_type) + { + case SADB_X_CREDTYPE_X509: + (*ipr)->ref_type = IPSP_CRED_X509; + break; + case SADB_X_CREDTYPE_KEYNOTE: + (*ipr)->ref_type = IPSP_CRED_KEYNOTE; + break; + default: + FREE(*ipr, M_CREDENTIALS); + *ipr = NULL; + return; + } + (*ipr)->ref_count = 1; + (*ipr)->ref_malloctype = M_CREDENTIALS; + bcopy((void *) sadb_cred + sizeof(struct sadb_x_cred), + (*ipr) + 1, (*ipr)->ref_len); +} + +/* + * Import an identity payload into the TDB. + */ +void +import_identity(struct tdb *tdb, struct sadb_ident *sadb_ident, int type) +{ + struct ipsec_ref **ipr; + + if (!sadb_ident) + return; + + if (type == PFKEYV2_IDENTITY_SRC) + ipr = &tdb->tdb_srcid; + else + ipr = &tdb->tdb_dstid; + + MALLOC(*ipr, struct ipsec_ref *, EXTLEN(sadb_ident) - + sizeof(struct sadb_ident) + sizeof(struct ipsec_ref), M_CREDENTIALS, + M_WAITOK); + (*ipr)->ref_len = EXTLEN(sadb_ident) - sizeof(struct sadb_ident); + switch (sadb_ident->sadb_ident_type) + { + case SADB_IDENTTYPE_PREFIX: + (*ipr)->ref_type = IPSP_IDENTITY_PREFIX; + break; + case SADB_IDENTTYPE_FQDN: + (*ipr)->ref_type = IPSP_IDENTITY_FQDN; + break; + case SADB_IDENTTYPE_USERFQDN: + (*ipr)->ref_type = IPSP_IDENTITY_USERFQDN; + break; + case SADB_X_IDENTTYPE_CONNECTION: + (*ipr)->ref_type = IPSP_IDENTITY_CONNECTION; + break; + default: + FREE(*ipr, M_CREDENTIALS); + *ipr = NULL; + return; + } + (*ipr)->ref_count = 1; + (*ipr)->ref_malloctype = M_CREDENTIALS; + bcopy((void *) sadb_ident + sizeof(struct sadb_ident), (*ipr) + 1, + (*ipr)->ref_len); +} + +void +export_credentials(void **p, struct tdb *tdb, int dstcred) +{ + struct ipsec_ref **ipr; + struct sadb_x_cred *sadb_cred = (struct sadb_x_cred *) *p; + + if (dstcred == PFKEYV2_CRED_REMOTE) + ipr = &tdb->tdb_remote_cred; + else + ipr = &tdb->tdb_local_cred; + + sadb_cred->sadb_x_cred_len = (sizeof(struct sadb_x_cred) + + PADUP((*ipr)->ref_len)) / sizeof(uint64_t); + + switch ((*ipr)->ref_type) + { + case IPSP_CRED_KEYNOTE: + sadb_cred->sadb_x_cred_type = SADB_X_CREDTYPE_KEYNOTE; + break; + case IPSP_CRED_X509: + sadb_cred->sadb_x_cred_type = SADB_X_CREDTYPE_X509; + break; + } + *p += sizeof(struct sadb_x_cred); + bcopy((*ipr) + 1, *p, (*ipr)->ref_len); + *p += PADUP((*ipr)->ref_len); +} + +void +export_auth(void **p, struct tdb *tdb, int dstauth) +{ + struct ipsec_ref **ipr; + struct sadb_x_cred *sadb_auth = (struct sadb_x_cred *) *p; + + if (dstauth == PFKEYV2_AUTH_REMOTE) + ipr = &tdb->tdb_remote_auth; + else + ipr = &tdb->tdb_local_auth; + + sadb_auth->sadb_x_cred_len = (sizeof(struct sadb_x_cred) + + PADUP((*ipr)->ref_len)) / sizeof(uint64_t); + + switch ((*ipr)->ref_type) + { + case IPSP_CRED_KEYNOTE: + sadb_auth->sadb_x_cred_type = SADB_X_CREDTYPE_KEYNOTE; + break; + case IPSP_CRED_X509: + sadb_auth->sadb_x_cred_type = SADB_X_CREDTYPE_X509; + break; + } + *p += sizeof(struct sadb_x_cred); + bcopy((*ipr) + 1, *p, (*ipr)->ref_len); + *p += PADUP((*ipr)->ref_len); +} + +void +export_identity(void **p, struct tdb *tdb, int type) +{ + struct ipsec_ref **ipr; + struct sadb_ident *sadb_ident = (struct sadb_ident *) *p; + + if (type == PFKEYV2_IDENTITY_SRC) + ipr = &tdb->tdb_srcid; + else + ipr = &tdb->tdb_dstid; + + sadb_ident->sadb_ident_len = (sizeof(struct sadb_ident) + + PADUP((*ipr)->ref_len)) / sizeof(uint64_t); + switch ((*ipr)->ref_type) + { + case IPSP_IDENTITY_PREFIX: + sadb_ident->sadb_ident_type = SADB_IDENTTYPE_PREFIX; + break; + case IPSP_IDENTITY_FQDN: + sadb_ident->sadb_ident_type = SADB_IDENTTYPE_FQDN; + break; + case IPSP_IDENTITY_USERFQDN: + sadb_ident->sadb_ident_type = SADB_IDENTTYPE_USERFQDN; + break; + case IPSP_IDENTITY_CONNECTION: + sadb_ident->sadb_ident_type = SADB_X_IDENTTYPE_CONNECTION; + break; + } + *p += sizeof(struct sadb_ident); + bcopy((*ipr) + 1, *p, (*ipr)->ref_len); + *p += PADUP((*ipr)->ref_len); +} + +/* ... */ +void +import_key(struct ipsecinit *ii, struct sadb_key *sadb_key, int type) +{ + if (!sadb_key) + return; + + if (type == PFKEYV2_ENCRYPTION_KEY) + { /* Encryption key */ + ii->ii_enckeylen = sadb_key->sadb_key_bits / 8; + ii->ii_enckey = (void *)sadb_key + sizeof(struct sadb_key); + } + else + { + ii->ii_authkeylen = sadb_key->sadb_key_bits / 8; + ii->ii_authkey = (void *)sadb_key + sizeof(struct sadb_key); + } +} + +void +export_key(void **p, struct tdb *tdb, int type) +{ + struct sadb_key *sadb_key = (struct sadb_key *) *p; + + if (type == PFKEYV2_ENCRYPTION_KEY) + { + sadb_key->sadb_key_len = (sizeof(struct sadb_key) + + PADUP(tdb->tdb_emxkeylen)) / + sizeof(uint64_t); + sadb_key->sadb_key_bits = tdb->tdb_emxkeylen * 8; + *p += sizeof(struct sadb_key); + bcopy(tdb->tdb_emxkey, *p, tdb->tdb_emxkeylen); + *p += PADUP(tdb->tdb_emxkeylen); + } + else + { + sadb_key->sadb_key_len = (sizeof(struct sadb_key) + + PADUP(tdb->tdb_amxkeylen)) / + sizeof(uint64_t); + sadb_key->sadb_key_bits = tdb->tdb_amxkeylen * 8; + *p += sizeof(struct sadb_key); + bcopy(tdb->tdb_amxkey, *p, tdb->tdb_amxkeylen); + *p += PADUP(tdb->tdb_amxkeylen); + } +} |