コード例 #1
0
ファイル: nat_traversal.c プロジェクト: yottanami/libreswan
static void natd_hash(const struct hash_desc *hasher, unsigned char *hash,
		const u_int8_t *icookie, const u_int8_t *rcookie,
		const ip_address *ip,
		u_int16_t port /* host order */)
{
	union hash_ctx ctx;

	if (is_zero_cookie(icookie))
		DBG(DBG_NATT, DBG_log("natd_hash: Warning, icookie is zero !!"));
	if (is_zero_cookie(rcookie))
		DBG(DBG_NATT, DBG_log("natd_hash: Warning, rcookie is zero !!"));

	/*
	 * RFC 3947
	 *
	 *   HASH = HASH(CKY-I | CKY-R | IP | Port)
	 *
	 * All values in network order
	 */
	hasher->hash_init(&ctx);
	hasher->hash_update(&ctx, icookie, COOKIE_SIZE);
	hasher->hash_update(&ctx, rcookie, COOKIE_SIZE);
	switch (addrtypeof(ip)) {
	case AF_INET:
		hasher->hash_update(&ctx,
				(const u_char *)&ip->u.v4.sin_addr.s_addr,
				sizeof(ip->u.v4.sin_addr.s_addr));
		break;
	case AF_INET6:
		hasher->hash_update(&ctx,
				(const u_char *)&ip->u.v6.sin6_addr.s6_addr,
				sizeof(ip->u.v6.sin6_addr.s6_addr));
		break;
	}
	{
		u_int16_t netorder_port = htons(port);

		hasher->hash_update(&ctx, (const u_char *)&netorder_port, sizeof(netorder_port));
	}
	hasher->hash_final(hash, &ctx);
	DBG(DBG_NATT, {
			DBG_log("natd_hash: hasher=%p(%d)", hasher,
				(int)hasher->hash_digest_len);
			DBG_dump("natd_hash: icookie=", icookie, COOKIE_SIZE);
			DBG_dump("natd_hash: rcookie=", rcookie, COOKIE_SIZE);
			switch (addrtypeof(ip)) {
			case AF_INET:
				DBG_dump("natd_hash: ip=",
					&ip->u.v4.sin_addr.s_addr,
					sizeof(ip->u.v4.sin_addr.s_addr));
				break;
			}
			DBG_log("natd_hash: port=%d", port);
			DBG_dump("natd_hash: hash=", hash,
				hasher->hash_digest_len);
		});
コード例 #2
0
ファイル: nat_traversal.c プロジェクト: rgbriggs/libreswan
static void natd_hash(const struct hash_desc *hasher, unsigned char *hash,
		const u_int8_t *icookie, const u_int8_t *rcookie,
		const ip_address *ip,
		u_int16_t port /* host order */)
{
	if (is_zero_cookie(icookie))
		DBG(DBG_NATT, DBG_log("natd_hash: Warning, icookie is zero !!"));
	if (is_zero_cookie(rcookie))
		DBG(DBG_NATT, DBG_log("natd_hash: Warning, rcookie is zero !!"));

	/*
	 * RFC 3947
	 *
	 *   HASH = HASH(CKY-I | CKY-R | IP | Port)
	 *
	 * All values in network order
	 */
	struct crypt_hash *ctx = crypt_hash_init(hasher, "NATD", DBG_CRYPT);
	crypt_hash_digest_bytes(ctx, "ICOOKIE", icookie, COOKIE_SIZE);
	crypt_hash_digest_bytes(ctx, "RCOOKIE", rcookie, COOKIE_SIZE);
	switch (addrtypeof(ip)) {
	case AF_INET:
		crypt_hash_digest_bytes(ctx, "SIN_ADDR",
					(const u_char *)&ip->u.v4.sin_addr.s_addr,
					sizeof(ip->u.v4.sin_addr.s_addr));
		break;
	case AF_INET6:
		crypt_hash_digest_bytes(ctx, "SIN6_ADDR",
					(const u_char *)&ip->u.v6.sin6_addr.s6_addr,
					sizeof(ip->u.v6.sin6_addr.s6_addr));
		break;
	}
	{
		u_int16_t netorder_port = htons(port);
		crypt_hash_digest_bytes(ctx, "PORT",
					&netorder_port, sizeof(netorder_port));
	}
	crypt_hash_final_bytes(&ctx, hash, hasher->hash_digest_len);
	DBG(DBG_NATT, {
			DBG_log("natd_hash: hasher=%p(%d)", hasher,
				(int)hasher->hash_digest_len);
			DBG_dump("natd_hash: icookie=", icookie, COOKIE_SIZE);
			DBG_dump("natd_hash: rcookie=", rcookie, COOKIE_SIZE);
			switch (addrtypeof(ip)) {
			case AF_INET:
				DBG_dump("natd_hash: ip=",
					&ip->u.v4.sin_addr.s_addr,
					sizeof(ip->u.v4.sin_addr.s_addr));
				break;
			}
			DBG_log("natd_hash: port=%d", port);
			DBG_dump("natd_hash: hash=", hash,
				hasher->hash_digest_len);
		});
コード例 #3
0
ファイル: nat_traversal.c プロジェクト: OPSF/uClinux
static void _natd_hash(const struct hash_desc *hasher, unsigned char *hash
		       , u_int8_t *icookie, u_int8_t *rcookie
		       , const ip_address *ip, u_int16_t port)
{
	union hash_ctx ctx;

	if (is_zero_cookie(icookie))
		DBG_log("_natd_hash: Warning, icookie is zero !!");
	if (is_zero_cookie(rcookie))
		DBG_log("_natd_hash: Warning, rcookie is zero !!");

	/**
	 * draft-ietf-ipsec-nat-t-ike-01.txt
	 *
	 *   HASH = HASH(CKY-I | CKY-R | IP | Port)
	 *
	 * All values in network order
	 */
	hasher->hash_init(&ctx);
	hasher->hash_update(&ctx, icookie, COOKIE_SIZE);
	hasher->hash_update(&ctx, rcookie, COOKIE_SIZE);
	switch (addrtypeof(ip)) {
		case AF_INET:
			hasher->hash_update(&ctx,
				(const u_char *)&ip->u.v4.sin_addr.s_addr,
				sizeof(ip->u.v4.sin_addr.s_addr));
			break;
		case AF_INET6:
			hasher->hash_update(&ctx,
				(const u_char *)&ip->u.v6.sin6_addr.s6_addr,
				sizeof(ip->u.v6.sin6_addr.s6_addr));
			break;
	}
	hasher->hash_update(&ctx, (const u_char *)&port, sizeof(u_int16_t));
	hasher->hash_final(hash, &ctx);
#ifdef NAT_D_DEBUG
	DBG(DBG_NATT,
		DBG_log("_natd_hash: hasher=%p(%d)", hasher, (int)hasher->hash_digest_len);
		DBG_dump("_natd_hash: icookie=", icookie, COOKIE_SIZE);
		DBG_dump("_natd_hash: rcookie=", rcookie, COOKIE_SIZE);
		switch (addrtypeof(ip)) {
			case AF_INET:
				DBG_dump("_natd_hash: ip=", &ip->u.v4.sin_addr.s_addr,
					sizeof(ip->u.v4.sin_addr.s_addr));
				break;
		}
		DBG_log("_natd_hash: port=%d", ntohs(port));
		DBG_dump("_natd_hash: hash=", hash, hasher->hash_digest_len);
	);
コード例 #4
0
ファイル: demux.c プロジェクト: mkj/libreswan
/* process an input packet, possibly generating a reply.
 *
 * If all goes well, this routine eventually calls a state-specific
 * transition function.
 */
void process_packet(struct msg_digest **mdp)
{
	struct msg_digest *md = *mdp;
	int vmaj, vmin;

	if (!in_struct(&md->hdr, &isakmp_hdr_desc, &md->packet_pbs,
		       &md->message_pbs)) {
		/* The packet was very badly mangled. We can't be sure of any
		 * content - not even to look for major version number!
		 * So we'll just drop it.
		 */
		libreswan_log("Received packet with mangled IKE header - dropped");
		send_notification_from_md(md, PAYLOAD_MALFORMED);
		return;
	}

	if (md->packet_pbs.roof > md->message_pbs.roof) {
		/* Some (old?) versions of the Cisco VPN client send an additional
		 * 16 bytes of zero bytes - Complain but accept it
		 */
		DBG(DBG_CONTROL, {
			DBG_log(
			"size (%u) in received packet is larger than the size "
			"specified in ISAKMP HDR (%u) - ignoring extraneous bytes",
			(unsigned) pbs_room(&md->packet_pbs),
			md->hdr.isa_length);
			DBG_dump("extraneous bytes:", md->message_pbs.roof,
				md->packet_pbs.roof - md->message_pbs.roof);
		});
コード例 #5
0
ファイル: v2-child.c プロジェクト: hydromet/libreswan
int main(int argc, char *argv[])
{
	struct state st1;

	progname = argv[0];
	cur_debugging = DBG_CRYPT | DBG_KERNEL | DBG_PARSING;

	memset(&st1, 0, sizeof(st1));
	pluto_shared_secrets_file = "../../baseconfigs/east/etc/ipsec.secrets";

	lsw_init_ipsecdir("../../baseconfigs/east/etc/ipsec.d");
	lsw_init_rootdir("../../baseconfigs/east");

	/* initialize list of moduli */
	init_crypto();
	load_lswcrypto();

	init_seam_kernelalgs();

	/* now derive the keys for the CHILD_SA */
	{
		struct ipsec_proto_info *ipi;

		setchunk(st1.st_skey_d, tc3_results_skey_d,
			 sizeof(tc3_results_skey_d));

		ipi = &st1.st_esp;
		ipi->attrs.transattrs.encrypt   = IKEv2_ENCR_AES_CBC;
		ipi->attrs.transattrs.enckeylen = 128;
		ipi->attrs.transattrs.integ_hash = alg_info_esp_v2tov1aa(
			IKEv2_AUTH_HMAC_SHA1_96);

		ikev2_derive_child_keys(&st1);

		DBG_dump("our  keymat: ",
			 ipi->our_keymat,
			 ipi->keymat_len);

		DBG_dump("peer keymat: ",
			 ipi->peer_keymat,
			 ipi->keymat_len);
	}

	exit(0);
}
コード例 #6
0
ファイル: crypt_ke.c プロジェクト: 1309578252/Openswan
void calc_nonce(struct pluto_crypto_req *r)
{
  struct pcr_kenonce *kn = &r->pcr_d.kn;

  pluto_crypto_allocchunk(&kn->thespace, &kn->n, DEFAULT_NONCE_SIZE);
  get_rnd_bytes(wire_chunk_ptr(kn, &(kn->n)), DEFAULT_NONCE_SIZE);

  DBG(DBG_CRYPT,
      DBG_dump("Generated nonce:\n"
	       , wire_chunk_ptr(kn, &(kn->n))
	       , DEFAULT_NONCE_SIZE));
}
コード例 #7
0
ファイル: hmac.c プロジェクト: jgimenez/libreswan
void hmac_update(struct hmac_ctx *ctx,
		 const u_char *data, size_t data_len)
{
	DBG(DBG_CRYPT, DBG_dump("hmac_update data value: ", data, data_len));
	if (data_len > 0) {
		DBG(DBG_CRYPT, DBG_log("hmac_update: inside if"));
		SECStatus status = PK11_DigestOp(ctx->ctx_nss, data, data_len);
		DBG(DBG_CRYPT, DBG_log("hmac_update: after digest"));
		PR_ASSERT(status == SECSuccess);
		DBG(DBG_CRYPT, DBG_log("hmac_update: after assert"));
	}
}
コード例 #8
0
ファイル: demux.c プロジェクト: pombredanne/libreswan
/* process an input packet, possibly generating a reply.
 *
 * If all goes well, this routine eventually calls a state-specific
 * transition function.
 */
void process_packet(struct msg_digest **mdp)
{
	struct msg_digest *md = *mdp;
	struct state *st = NULL;
	int vmaj, vmin;
	enum state_kind from_state = STATE_UNDEFINED;   /* state we started in */

#define SEND_NOTIFICATION(t) { \
		if (st) \
			send_notification_from_state(st, from_state, t); \
		else \
			send_notification_from_md(md, t); }

	if (!in_struct(&md->hdr, &isakmp_hdr_desc, &md->packet_pbs,
		       &md->message_pbs)) {
		/*
		 * The packet was very badly mangled. We can't be sure of any
		 * content - not even to look for major version number!
		 * So we'll just silently drop it
		 */
		libreswan_log("Received packet with mangled IKE header - dropped");
		SEND_NOTIFICATION(PAYLOAD_MALFORMED);
		return;
	}

	if (md->packet_pbs.roof < md->message_pbs.roof) {
		/* I don't think this can happen if in_struct() did not fail */
		libreswan_log(
			"received packet size (%u) is smaller than from "
			"size specified in ISAKMP HDR (%u) - packet dropped",
			(unsigned) pbs_room(&md->packet_pbs),
			md->hdr.isa_length);
		/* abort processing corrupt packet */
		return;
	} else if (md->packet_pbs.roof > md->message_pbs.roof) {
		/*
		 * Some (old?) versions of the Cisco VPN client send an additional
		 * 16 bytes of zero bytes - Complain but accept it
		 */
		DBG(DBG_CONTROL, {
			DBG_log(
			"size (%u) in received packet is larger than the size "
			"specified in ISAKMP HDR (%u) - ignoring extraneous bytes",
			(unsigned) pbs_room(&md->packet_pbs),
			md->hdr.isa_length);
			DBG_dump("extraneous bytes:", md->message_pbs.roof,
				md->packet_pbs.roof - md->message_pbs.roof);
		});
コード例 #9
0
ファイル: ikev2_rsa.c プロジェクト: dotmark/libreswan
bool ikev2_calculate_rsa_sha1(struct state *st,
			      enum phase1_role role,
			      unsigned char *idhash,
			      pb_stream *a_pbs)
{
	unsigned char signed_octets[SHA1_DIGEST_SIZE + 16];
	size_t signed_len;
	const struct connection *c = st->st_connection;
	const struct RSA_private_key *k = get_RSA_private_key(c);
	unsigned int sz;

	if (k == NULL)
		return FALSE; /* failure: no key to use */

	sz = k->pub.k;

	memcpy(signed_octets, der_digestinfo, der_digestinfo_len);

	ikev2_calculate_sighash(st, role, idhash,
				st->st_firstpacket_me,
				signed_octets + der_digestinfo_len);
	signed_len = der_digestinfo_len + SHA1_DIGEST_SIZE;

	passert(RSA_MIN_OCTETS <= sz && 4 + signed_len < sz &&
		sz <= RSA_MAX_OCTETS);

	DBG(DBG_CRYPT,
	    DBG_dump("v2rsa octets", signed_octets, signed_len));

	{
		/* now generate signature blob */
		u_char sig_val[RSA_MAX_OCTETS];
		int shr;

		shr = sign_hash(k, signed_octets, signed_len, sig_val, sz);
		if (shr == 0)
			return FALSE;
		passert(shr == (int)sz);
		if (!out_raw(sig_val, sz, a_pbs, "rsa signature"))
			return FALSE;
	}

	return TRUE;
}
コード例 #10
0
ファイル: ikev2_crypto.c プロジェクト: 1309578252/Openswan
bool ikev2_calculate_rsa_sha1(struct state *st
			      , enum phase1_role role
			      , unsigned char *idhash
			      , pb_stream *a_pbs)
{
	unsigned char  signed_octets[SHA1_DIGEST_SIZE+16];
	size_t         signed_len;
	const struct connection *c = st->st_connection;
	const struct RSA_private_key *k = get_RSA_private_key(c);
	unsigned int sz;

	if (k == NULL)
	    return 0;	/* failure: no key to use */

	sz = k->pub.k;

        /*
         * this is the prefix of the ASN/DER goop that lives inside RSA-SHA1
         * signatures.  If the signing hash changes, this needs to change
         * too, but this function is specific to RSA-SHA1.
         */
	memcpy(signed_octets, der_digestinfo, der_digestinfo_len);

	ikev2_calculate_sighash(st, role, idhash
				, st->st_firstpacket_me
				, signed_octets+der_digestinfo_len);
	signed_len = der_digestinfo_len + SHA1_DIGEST_SIZE;

	passert(RSA_MIN_OCTETS <= sz && 4 + signed_len < sz && sz <= RSA_MAX_OCTETS);

	DBG(DBG_CRYPT
	    , DBG_dump("v2rsa octets", signed_octets, signed_len));

	{
		u_char sig_val[RSA_MAX_OCTETS];

		/* now generate signature blob */
		sign_hash(k, signed_octets, signed_len
			  , sig_val, sz);
		out_raw(sig_val, sz, a_pbs, "rsa signature");
	}

	return TRUE;
}
コード例 #11
0
ファイル: crypt_ke.c プロジェクト: 1309578252/Openswan
void calc_ke(struct pluto_crypto_req *r)
{
    MP_INT mp_g;
    MP_INT secret;
    chunk_t gi;
    struct pcr_kenonce *kn = &r->pcr_d.kn;
    const struct oakley_group_desc *group;

    group = lookup_group(kn->oakley_group);

    pluto_crypto_allocchunk(&kn->thespace
			    , &kn->secret
			    , LOCALSECRETSIZE);

    get_rnd_bytes(wire_chunk_ptr(kn, &(kn->secret)), LOCALSECRETSIZE);

    n_to_mpz(&secret, wire_chunk_ptr(kn, &(kn->secret)), LOCALSECRETSIZE);

    mpz_init(&mp_g);

    oswcrypto.mod_exp(&mp_g, group->generator, &secret, group->modulus);

    gi = mpz_to_n(&mp_g, group->bytes);

    pluto_crypto_allocchunk(&kn->thespace, &kn->gi, gi.len);

    {
	char *gip = wire_chunk_ptr(kn, &(kn->gi));

	memcpy(gip, gi.ptr, gi.len);
    }

    DBG(DBG_CRYPT,
	DBG_dump("Local DH secret:\n"
		 , wire_chunk_ptr(kn, &(kn->secret))
		 , LOCALSECRETSIZE);
	DBG_dump_chunk("Public DH value sent:\n", gi));

    /* clean up after ourselves */
    mpz_clear(&mp_g);
    mpz_clear(&secret);
    freeanychunk(gi);
}
コード例 #12
0
ファイル: ikev2_psk.c プロジェクト: fatenever/libreswan
bool ikev2_calculate_psk_auth(struct state *st,
			      enum original_role role,
			      unsigned char *idhash,
			      pb_stream *a_pbs)
{
	unsigned int hash_len =  st->st_oakley.prf_hasher->hash_digest_len;
	unsigned char signed_octets[hash_len];

	if (!ikev2_calculate_psk_sighash(st, role, idhash,
					 st->st_firstpacket_me,
					 signed_octets))
		return FALSE;

	DBG(DBG_PRIVATE,
	    DBG_dump("PSK auth octets", signed_octets, hash_len ));

	if (!out_raw(signed_octets, hash_len, a_pbs, "PSK auth"))
		return FALSE;

	return TRUE;
}
コード例 #13
0
ファイル: hmac.c プロジェクト: jgimenez/libreswan
void nss_symkey_log(PK11SymKey *key, const char *msg)
{
	if (key != NULL) {
		DBG(DBG_CRYPT, DBG_log("computed key %s with length =%d", msg,
				       PK11_GetKeyLength(key)));
	} else {
		DBG_log("NULL key %s", msg);
	}

	if (!PK11_IsFIPS()) {
		if (key != NULL) {
			SECStatus status = PK11_ExtractKeyValue(key);
			PR_ASSERT(status == SECSuccess);
			SECItem *keydata = PK11_GetKeyData(key);

			DBG(DBG_CRYPT, DBG_dump("value: ", keydata->data,
						keydata->len));

			/* SECITEM_FreeItem(keydata, PR_TRUE); */
		}
	}
}
コード例 #14
0
ファイル: nat_traversal.c プロジェクト: a1phageek/kyocera-kr1
/**
 * nat_traversal_natoa_lookup()
 * 
 * Look for NAT-OA in message
 */
void nat_traversal_natoa_lookup(struct msg_digest *md)
{
	struct payload_digest *p;
	struct state *st = md->st;
	int i;
	ip_address ip;

	if (!st || !md->iface) {
		loglog(RC_LOG_SERIOUS, "NAT-Traversal: assert failed %s:%d",
			__FILE__, __LINE__);
		return;
	}

	/** Count NAT-OA **/
	for (p = md->chain[ISAKMP_NEXT_NATOA_R], i=0; p != NULL; p = p->next, i++);

#if 0
	DBG_log("NAT-Traversal: received %d NAT-OA.", i);
#endif

	if (i==0) {
		return;
	}
	else if (!(st->nat_traversal & LELEM(NAT_TRAVERSAL_NAT_BHND_PEER))) {
		loglog(RC_LOG_SERIOUS, "NAT-Traversal: received %d NAT-OA. "
			"ignored because peer is not NATed", i);
		return;
	}
	else if (i>1) {
		loglog(RC_LOG_SERIOUS, "NAT-Traversal: received %d NAT-OA. "
			"using first, ignoring others", i);
	}

	/** Take first **/
	p = md->chain[ISAKMP_NEXT_NATOA_R];

	DBG(DBG_PARSING,
		DBG_dump("NAT-OA:", p->pbs.start, pbs_room(&p->pbs));
	);
コード例 #15
0
ファイル: ikev2_psk.c プロジェクト: fatenever/libreswan
stf_status ikev2_verify_psk_auth(struct state *st,
				 enum original_role role,
				 unsigned char *idhash,
				 pb_stream *sig_pbs)
{
	unsigned int hash_len =  st->st_oakley.prf_hasher->hash_digest_len;
	unsigned char calc_hash[hash_len];
	size_t sig_len = pbs_left(sig_pbs);

	enum original_role invertrole;

	invertrole = (role == ORIGINAL_INITIATOR ? ORIGINAL_RESPONDER : ORIGINAL_INITIATOR);

	if (sig_len != hash_len) {
		libreswan_log("negotiated prf: %s ",
			      st->st_oakley.prf_hasher->common.name);
		libreswan_log(
			"I2 hash length:%lu does not match with PRF hash len %lu",
			(long unsigned) sig_len,
			(long unsigned) hash_len);
		return STF_FAIL;
	}

	if (!ikev2_calculate_psk_sighash(st, invertrole, idhash,
					 st->st_firstpacket_him, calc_hash))
		return STF_FAIL;

	DBG(DBG_PRIVATE,
	    DBG_dump("Received PSK auth octets", sig_pbs->cur, sig_len);
	    DBG_dump("Calculated PSK auth octets", calc_hash, hash_len));

	if (memeq(sig_pbs->cur, calc_hash, hash_len) ) {
		return STF_OK;
	} else {
		libreswan_log("AUTH mismatch: Received AUTH != computed AUTH");
		return STF_FAIL;
	}
}
コード例 #16
0
ファイル: vendor.c プロジェクト: christianrober/R05R4-RC2
void init_vendorid(void)
{
	struct vid_struct *vid;
	MD5_CTX ctx;
	int i;

	for (vid = _vid_tab; vid->id; vid++) {
		if (vid->flags & VID_STRING) {
			/** VendorID is a string **/
			vid->vid = strdup(vid->data);
			vid->vid_len = strlen(vid->data);
		}
		else if (vid->flags & VID_MD5HASH) {
			/** VendorID is a string to hash with MD5 **/
			char *vidm =  malloc(MD5_DIGEST_SIZE);
			vid->vid = vidm;
			if (vidm) {
				MD5Init(&ctx);
				MD5Update(&ctx, (unsigned char *)vid->data, strlen(vid->data));
				MD5Final(vidm, &ctx);
				vid->vid_len = MD5_DIGEST_SIZE;
			}
		}
		else if (vid->flags & VID_FSWAN_HASH) {
			/** FreeS/WAN 2.00+ specific hash **/
#define FSWAN_VID_SIZE 12
			unsigned char hash[MD5_DIGEST_SIZE];
			char *vidm =  malloc(FSWAN_VID_SIZE);
			vid->vid = vidm;
			if (vidm) {
				MD5Init(&ctx);
				MD5Update(&ctx, (unsigned char *)vid->data, strlen(vid->data));
				MD5Final(hash, &ctx);
				vidm[0] = 'O';
				vidm[1] = 'E';
#if FSWAN_VID_SIZE - 2 <= MD5_DIGEST_SIZE
				memcpy(vidm + 2, hash, FSWAN_VID_SIZE - 2);
#else
				memcpy(vidm + 2, hash, MD5_DIGEST_SIZE);
				memset(vidm + 2 + MD5_DIGEST_SIZE, '\0',
					FSWAN_VID_SIZE - 2 - MD5_DIGEST_SIZE);
#endif
				for (i = 2; i < FSWAN_VID_SIZE; i++) {
					vidm[i] &= 0x7f;
					vidm[i] |= 0x40;
				}
				vid->vid_len = FSWAN_VID_SIZE;
			}
		}

		if (vid->descr == NULL) {
			/** Find something to display **/
			vid->descr = vid->data;
		}
#if 0
		DBG_log("vendorid_init: %d [%s]",
			vid->id,
			vid->descr ? vid->descr : ""
			);
		if (vid->vid) DBG_dump("VID:", vid->vid, vid->vid_len);
#endif
	}
	_vid_struct_init = 1;
}
コード例 #17
0
ファイル: ikev2_crypto.c プロジェクト: 1309578252/Openswan
err_t
try_RSA_signature_v2(const u_char hash_val[MAX_DIGEST_LEN]
		     , size_t hash_len
		     , const pb_stream *sig_pbs, struct pubkey *kr
		     , struct state *st)
{
    const u_char *sig_val = sig_pbs->cur;
    size_t sig_len = pbs_left(sig_pbs);
    u_char s[RSA_MAX_OCTETS];	/* for decrypted sig_val */
    u_char *sig;
    unsigned int padlen;
    const struct RSA_public_key *k = &kr->u.rsa;

    if (k == NULL)
	return "1""no key available";	/* failure: no key to use */

    /* decrypt the signature -- reversing RSA_sign_hash */
    if (sig_len != k->k)
    {
        DBG_log("sig_len: %u != k->k: %u"
                , (unsigned int)sig_len, (unsigned int)k->k);
	return "1""SIG length does not match public key length";
    }

    /* actual exponentiation; see PKCS#1 v2.0 5.1 */
    {
	chunk_t temp_s;
	MP_INT c;

	n_to_mpz(&c, sig_val, sig_len);
	oswcrypto.mod_exp(&c, &c, &k->e, &k->n);

	temp_s = mpz_to_n(&c, sig_len);	/* back to octets */
	memcpy(s, temp_s.ptr, sig_len);
	pfree(temp_s.ptr);
	mpz_clear(&c);
    }

    /* check signature contents */
    /* verify padding */
    padlen = sig_len - 3 - (hash_len+der_digestinfo_len);
    /* now check padding */
    sig = s;

    DBG(DBG_CRYPT,
	DBG_dump("v2rsa decrypted SIG1:", sig, sig_len));

    if(sig[0]    != 0x00
       || sig[1] != 0x01
       || sig[padlen+2] != 0x00) {
	return "2""SIG padding does not check out";
    }

    /* skip padding */
    sig += padlen+3;

    /* 2 verify that the has was done with SHA1 */
    if(memcmp(der_digestinfo, sig, der_digestinfo_len)!=0) {
	return "SIG not performed with SHA1";
    }

    sig += der_digestinfo_len;

    DBG(DBG_CRYPT,
	DBG_dump("v2rsa decrypted SIG:", hash_val, hash_len);
	DBG_dump("v2rsa computed hash:", sig, hash_len);
    );
コード例 #18
0
ファイル: signatures_nss.c プロジェクト: 1309578252/Openswan
err_t RSA_signature_verify_nss(const struct RSA_public_key *k
                              , const u_char *hash_val, size_t hash_len
                               ,const u_char *sig_val, size_t sig_len)
{
   SECKEYPublicKey *publicKey;
   PRArenaPool *arena;
   SECStatus retVal = SECSuccess;
   SECItem nss_n, nss_e;
   SECItem signature, data;
   chunk_t n,e;

    /*Converting n and e to form public key in SECKEYPublicKey data structure*/

    arena = PORT_NewArena(DER_DEFAULT_CHUNKSIZE);
    if (arena == NULL) {
	PORT_SetError (SEC_ERROR_NO_MEMORY);
	return "10" "NSS error: Not enough memory to create arena";
    }

    publicKey = (SECKEYPublicKey *) PORT_ArenaZAlloc (arena, sizeof (SECKEYPublicKey));
    if (!publicKey) {
	PORT_FreeArena (arena, PR_FALSE);
	PORT_SetError (SEC_ERROR_NO_MEMORY);
	return "11" "NSS error: Not enough memory to create publicKey";
    }

    publicKey->arena = arena;
    publicKey->keyType = rsaKey;
    publicKey->pkcs11Slot = NULL;
    publicKey->pkcs11ID = CK_INVALID_HANDLE;

    /* Converting n(modulus) and e(exponent) from mpz_t form to chunk_t */
    n = mpz_to_n_autosize(&k->n);
    e = mpz_to_n_autosize(&k->e);

    /*Converting n and e to nss_n and nss_e*/
    nss_n.data = n.ptr;
    nss_n.len = (unsigned int)n.len;
    nss_n.type = siBuffer;

    nss_e.data = e.ptr;
    nss_e.len = (unsigned int)e.len;
    nss_e.type = siBuffer;

    retVal = SECITEM_CopyItem(arena, &publicKey->u.rsa.modulus, &nss_n);
    if (retVal == SECSuccess) {
	retVal = SECITEM_CopyItem (arena, &publicKey->u.rsa.publicExponent, &nss_e);
    }

    if(retVal != SECSuccess) {
	pfree(n.ptr);
	pfree(e.ptr);
	SECKEY_DestroyPublicKey (publicKey);
	return "12" "NSS error: Not able to copy modulus or exponent or both while forming SECKEYPublicKey structure";
    }
    signature.type = siBuffer;
    signature.data = DISCARD_CONST(unsigned char *, sig_val);
    signature.len  = (unsigned int)sig_len;

    data.len = (unsigned int)sig_len;
    data.data = alloc_bytes(data.len, "NSS decrypted signature");
    data.type = siBuffer;

    if(PK11_VerifyRecover(publicKey, &signature, &data, osw_return_nss_password_file_info()) == SECSuccess ) {
	DBG(DBG_CRYPT,DBG_dump("NSS RSA verify: decrypted sig: ", data.data, data.len));
    }
    else {
        DBG(DBG_CRYPT,DBG_log("NSS RSA verify: decrypting signature is failed"));
        return "13" "NSS error: Not able to decrypt";
    }

    if(memcmp(data.data+data.len-hash_len, hash_val, hash_len)!=0) {
	pfree(data.data);
	loglog(RC_LOG_SERIOUS, "RSA Signature NOT verified");
	return "14" "NSS error: Not able to verify";
    }

    DBG(DBG_CRYPT,DBG_dump("NSS RSA verify: hash value: ", hash_val, hash_len));

    pfree(data.data);
    pfree(n.ptr);
    pfree(e.ptr);
    SECKEY_DestroyPublicKey (publicKey);

    DBG(DBG_CRYPT, DBG_log("RSA Signature verified"));

    return NULL;
}
コード例 #19
0
ファイル: seam_commhandle.c プロジェクト: hydromet/libreswan
void recv_pcap_packet_gen(u_char *user,
			  const struct pcap_pkthdr *h,
			  const u_char *bytes)
{
	struct msg_digest *md;
	u_int32_t *dlt;
	struct iphdr  *ip;
	struct udphdr *udp;
	u_char    *ike;
	const struct iface_port *ifp = &if1;
	int packet_len;
	err_t from_ugh;

	union {
		struct sockaddr sa;
		struct sockaddr_in sa_in4;
		struct sockaddr_in6 sa_in6;
	} from;

	md = alloc_md();
	dlt = (u_int32_t *)bytes;
	if (*dlt != PF_INET)
		return;

	ip  = (struct iphdr *)(dlt + 1);
	udp = (struct udphdr *)(dlt + ip->ihl + 1);
	ike = (u_char *)(udp + 1);

	from.sa_in4.sin_addr.s_addr = ip->saddr;
	from.sa_in4.sin_port        = udp->source;

	md->iface = ifp;
	packet_len = h->len - (ike - bytes);

	happy(anyaddr(addrtypeof(&ifp->ip_addr), &md->sender));

	from_ugh = initaddr((void *) &from.sa_in4.sin_addr,
			    sizeof(from.sa_in4.sin_addr),
			    AF_INET, &md->sender);
	setportof(from.sa_in4.sin_port, &md->sender);
	md->sender_port = ntohs(from.sa_in4.sin_port);

	cur_from      = &md->sender;
	cur_from_port = md->sender_port;

	/* Clone actual message contents
	 * and set up md->packet_pbs to describe it.
	 */
	init_pbs(&md->packet_pbs,
		 clone_bytes(ike, packet_len,
			     "message buffer in comm_handle()"),
		 packet_len, "packet");

	DBG_log("*received %d bytes from %s:%u on %s (port=%d)",
		(int) pbs_room(&md->packet_pbs),
		ip_str(&md->sender), (unsigned) md->sender_port,
		ifp->ip_dev->id_rname,
		ifp->port);

	DBG_dump("", md->packet_pbs.start, pbs_room(&md->packet_pbs));

	process_packet(&md);

	if (md != NULL)
		release_md(md);

	cur_state = NULL;
	reset_cur_connection();
	cur_from = NULL;
}
コード例 #20
0
ファイル: crypt_ke.c プロジェクト: 1309578252/Openswan
void calc_ke(struct pluto_crypto_req *r)
{
    chunk_t  prime;
    chunk_t  base;
    SECKEYDHParams      dhp;
    PK11SlotInfo *slot = NULL;
    SECKEYPrivateKey *privk;
    SECKEYPublicKey   *pubk;
    struct pcr_kenonce *kn = &r->pcr_d.kn;
    const struct oakley_group_desc *group;

    group = lookup_group(kn->oakley_group);


    base  = mpz_to_n2(group->generator);
    prime = mpz_to_n2(group->modulus);

    DBG(DBG_CRYPT,DBG_dump_chunk("NSS: Value of Prime:\n", prime));
    DBG(DBG_CRYPT,DBG_dump_chunk("NSS: Value of base:\n", base));

    dhp.prime.data=prime.ptr;
    dhp.prime.len=prime.len;
    dhp.base.data=base.ptr;
    dhp.base.len=base.len;

    slot = PK11_GetBestSlot(CKM_DH_PKCS_KEY_PAIR_GEN,osw_return_nss_password_file_info());
    if(!slot) {
	loglog(RC_LOG_SERIOUS, "NSS: slot for DH key gen is NULL");
    }
    PR_ASSERT(slot!=NULL);

    while(1) {
	privk = PK11_GenerateKeyPair(slot, CKM_DH_PKCS_KEY_PAIR_GEN, &dhp, &pubk, PR_FALSE, PR_TRUE, osw_return_nss_password_file_info());
	if(!privk) {
	   loglog(RC_LOG_SERIOUS, "NSS: DH private key creation failed (err %d)", PR_GetError());
	}
	PR_ASSERT(privk!=NULL);

	if( group-> bytes == pubk->u.dh.publicValue.len ) {
	   DBG(DBG_CRYPT, DBG_log("NSS: generated dh priv and pub keys: %d\n", pubk->u.dh.publicValue.len));
	   break;
	} else {
	   DBG(DBG_CRYPT, DBG_log("NSS: generating dh priv and pub keys"));
	   if (privk) SECKEY_DestroyPrivateKey(privk);
	   if (pubk)  SECKEY_DestroyPublicKey(pubk);
	   }
    }

    pluto_crypto_allocchunk(&kn->thespace, &kn->secret, sizeof(SECKEYPrivateKey*));
    {
	char *gip = wire_chunk_ptr(kn, &(kn->secret));
	memcpy(gip, &privk, sizeof(SECKEYPrivateKey *));
    }

    pluto_crypto_allocchunk(&kn->thespace, &kn->gi, pubk->u.dh.publicValue.len);
    {
	char *gip = wire_chunk_ptr(kn, &(kn->gi));
	memcpy(gip, pubk->u.dh.publicValue.data, pubk->u.dh.publicValue.len);
    }

    pluto_crypto_allocchunk(&kn->thespace, &kn->pubk, sizeof(SECKEYPublicKey*));
    {
	char *gip = wire_chunk_ptr(kn, &(kn->pubk));
	memcpy(gip, &pubk, sizeof(SECKEYPublicKey*));
    }

    DBG(DBG_CRYPT,
       DBG_dump("NSS: Local DH secret:\n"
                , wire_chunk_ptr(kn, &(kn->secret))
                , sizeof(SECKEYPrivateKey*));
       DBG_dump("NSS: Public DH value sent(computed in NSS):\n", wire_chunk_ptr(kn, &(kn->gi)),pubk->u.dh.publicValue.len));

    DBG(DBG_CRYPT,
        DBG_dump("NSS: Local DH public value (pointer):\n"
                 , wire_chunk_ptr(kn, &(kn->pubk))
                 , sizeof(SECKEYPublicKey*)));

    /* clean up after ourselves */
    if (slot) {
	PK11_FreeSlot(slot);
    }
    /* if (privk){SECKEY_DestroyPrivateKey(privk);} */
    /* if (pubk){SECKEY_DestroyPublicKey(pubk);} */
    freeanychunk(prime);
    freeanychunk(base);
}
コード例 #21
0
ファイル: vendor.c プロジェクト: hydromet/libreswan
/*
 * Setup VendorID structs, and populate them
 * FIXME: This functions leaks a little bit, but these are one time leaks:
 * leak: 3 * vid->data, item size: 6
 * leak: self-vendor ID, item size: 37
 * leak: init_pluto_vendorid, item size: 13
 * leak: 2 * vid->data, item size: 13
 */
void init_vendorid(void)
{
	struct vid_struct *vid;

	for (vid = vid_tab; vid->id; vid++) {
		if (vid->flags & VID_SELF) {
			char *d;

			vid->vid = clone_str(
				ipsec_version_vendorid(), "init_pluto_vendorid");
			/* cut terminating NULL which won't go over the wire */
			vid->vid_len = strlen(vid->vid);
			d = alloc_bytes(strlen(vid->descr) + 256 +
					strlen(ipsec_version_vendorid()),
					"self-vendor ID");
			sprintf(d, "%s %s", vid->descr, ipsec_version_code());
			vid->descr = (const char *)d;
		} else if (vid->flags & VID_STRING) {
			/** VendorID is a string **/
			vid->vid = clone_str(vid->data, "vid->data");
			vid->vid_len = strlen(vid->data);
		} else if (vid->flags & VID_MD5HASH) {
			/** VendorID is a string to hash with MD5 **/
			unsigned char *vidm =  alloc_bytes(MD5_DIGEST_SIZE,
							   "VendorID MD5");
			vid->vid = (char *)vidm;
			if (vidm) {
				unsigned const char *d =
					(unsigned const char *)vid->data;
				MD5_CTX ctx;

				osMD5Init(&ctx);
				osMD5Update(&ctx, d, strlen(vid->data));
				osMD5Final(vidm, &ctx);
				vid->vid_len = MD5_DIGEST_SIZE;
			}
		} else if (vid->flags & VID_FSWAN_HASH) {
			/** FreeS/WAN 2.00+ specific hash **/
#define FSWAN_VID_SIZE 12
			unsigned char hash[MD5_DIGEST_SIZE];
			char *vidm =  alloc_bytes(FSWAN_VID_SIZE, "fswan VID");

			vid->vid = vidm;
			if (vidm) {
				MD5_CTX ctx;
				int i;

				osMD5Init(&ctx);
				osMD5Update(&ctx,
					    (const unsigned char *)vid->data, strlen(
						    vid->data));
				osMD5Final(hash, &ctx);
				vidm[0] = 'O';
				vidm[1] = 'E';
#if FSWAN_VID_SIZE <= 2 + MD5_DIGEST_SIZE
				memcpy(vidm + 2, hash, FSWAN_VID_SIZE - 2);	/* truncate hash */
#else
				memcpy(vidm + 2, hash, MD5_DIGEST_SIZE);
				memset(vidm + 2 + MD5_DIGEST_SIZE, '\0',
				       FSWAN_VID_SIZE - (2 + MD5_DIGEST_SIZE));	/* pad hash */
#endif
				for (i = 2; i < FSWAN_VID_SIZE; i++) {
					vidm[i] &= 0x7f;
					vidm[i] |= 0x40;
				}
				vid->vid_len = FSWAN_VID_SIZE;
			}
#undef FSWAN_VID_SIZE
		}

		if (vid->descr == NULL) {
			/** Find something to display **/
			vid->descr = vid->data;
		}
#if 1
		DBG_log("init_vendorid: %d [%s]",
			vid->id,
			vid->descr ? vid->descr : ""
			);
		if (vid->vid)
			DBG_dump("VID:", vid->vid, vid->vid_len);
#endif
	}
	vid_struct_init = 1;
}
コード例 #22
0
ファイル: nat_traversal.c プロジェクト: a1phageek/kyocera-kr1
void nat_traversal_natd_lookup(struct msg_digest *md)
{
	char hash[MAX_DIGEST_LEN];
	struct payload_digest *p;
	struct state *st = md->st;
	int i;

	if (!st || !md->iface || !st->st_oakley.hasher) {
		loglog(RC_LOG_SERIOUS, "NAT-Traversal: assert failed %s:%d",
			__FILE__, __LINE__);
		return;
	}

	/** Count NAT-D **/
	for (p = md->chain[ISAKMP_NEXT_NATD_R], i=0; p != NULL; p = p->next, i++);

	/**
	 * We need at least 2 NAT-D (1 for us, many for peer)
	 */
	if (i < 2) {
		loglog(RC_LOG_SERIOUS,
		"NAT-Traversal: Only %d NAT-D - Aborting NAT-Traversal negotiation", i);
		st->nat_traversal = 0;
		return;
	} 
#ifdef NAT_D_DEBUG
	else
		loglog(RC_LOG_SERIOUS,
		"NAT-Traversal: %d NAT-D - Continuing NAT-Traversal negotiation", i);
#endif


	/**
	 * First one with my IP & port
	 */
	p = md->chain[ISAKMP_NEXT_NATD_R];
	_natd_hash(st->st_oakley.hasher, hash, st->st_icookie, st->st_rcookie,
		&(md->iface->addr), ntohs(st->st_connection->this.host_port));
	if (!( (pbs_left(&p->pbs) == st->st_oakley.hasher->hash_digest_len) &&
		(memcmp(p->pbs.cur, hash, st->st_oakley.hasher->hash_digest_len)==0)
		)) {
#ifdef NAT_D_DEBUG
		DBG_log("NAT_TRAVERSAL_NAT_BHND_ME");
		DBG_dump("expected NAT-D:", hash, st->st_oakley.hasher->hash_digest_len);
		DBG_dump("received NAT-D:", p->pbs.cur, pbs_left(&p->pbs));
#endif
		st->nat_traversal |= LELEM(NAT_TRAVERSAL_NAT_BHND_ME);
	}

	/**
	 * The others with sender IP & port
	 */
	_natd_hash(st->st_oakley.hasher, hash, st->st_icookie, st->st_rcookie,
		&(md->sender), ntohs(md->sender_port));
	for (p = p->next, i=0 ; p != NULL; p = p->next) {
		if ( (pbs_left(&p->pbs) == st->st_oakley.hasher->hash_digest_len) &&
			(memcmp(p->pbs.cur, hash, st->st_oakley.hasher->hash_digest_len)==0)
			) {
			i++;
		}
	}
	if (!i) {
#ifdef NAT_D_DEBUG
		DBG_log("NAT_TRAVERSAL_NAT_BHND_PEER");
		DBG_dump("expected NAT-D:", hash, st->st_oakley.hasher->hash_digest_len);
		p = md->chain[ISAKMP_NEXT_NATD_R];
		for (p = p->next, i=0 ; p != NULL; p = p->next) {
			DBG_dump("received NAT-D:", p->pbs.cur, pbs_left(&p->pbs));
		}
#endif
		st->nat_traversal |= LELEM(NAT_TRAVERSAL_NAT_BHND_PEER);
	}
#ifdef FORCE_NAT_TRAVERSAL
	st->nat_traversal |= LELEM(NAT_TRAVERSAL_NAT_BHND_PEER);
	st->nat_traversal |= LELEM(NAT_TRAVERSAL_NAT_BHND_ME);
#endif
}
コード例 #23
0
ファイル: vendor.c プロジェクト: nawien-sharma/libreswan
/*
 * Setup VendorID structs, and populate them
 * FIXME: This functions leaks a little bit, but these are one time leaks:
 * leak: 3 * vid->data, item size: 6
 * leak: self-vendor ID, item size: 37
 * leak: 2 * vid->data, item size: 13
 */
void init_vendorid(void)
{
	struct vid_struct *vid;

	for (vid = vid_tab; vid->id; vid++) {
		if (vid->flags & VID_SELF) {
			vid->vid_len = strlen(vid->vid);
		} else if (vid->flags & VID_STRING) {
			/** VendorID is a string **/
			vid->vid = clone_str(vid->data, "vid->data (ignore)");
			/* clang 3.4 thinks that vid->data might be NULL but it won't be */
			vid->vid_len = strlen(vid->data);
		} else if (vid->flags & VID_MD5HASH) {
			/** VendorID is a string to hash with MD5 **/
			unsigned char *vidm = alloc_bytes(MD5_DIGEST_SIZE,
							 "VendorID MD5 (ignore)");
			const unsigned char *d = (const unsigned char *)vid->data;
			lsMD5_CTX ctx;

			vid->vid = (char *)vidm;

			lsMD5Init(&ctx);
			lsMD5Update(&ctx, d, strlen(vid->data));
			lsMD5Final(vidm, &ctx);
			vid->vid_len = MD5_DIGEST_SIZE;
		} else if (vid->flags & VID_FSWAN_HASH) {
			/** FreeS/WAN 2.00+ specific hash **/
#define FSWAN_VID_SIZE 12
			unsigned char hash[MD5_DIGEST_SIZE];
			char *vidm = alloc_bytes(FSWAN_VID_SIZE, "fswan VID (ignore)");
			lsMD5_CTX ctx;
			int i;

			vid->vid = vidm;

			lsMD5Init(&ctx);
			lsMD5Update(&ctx, (const unsigned char *)vid->data,
				strlen(vid->data));
			lsMD5Final(hash, &ctx);
			vidm[0] = 'O';
			vidm[1] = 'E';
#if FSWAN_VID_SIZE <= 2 + MD5_DIGEST_SIZE
			memcpy(vidm + 2, hash, FSWAN_VID_SIZE - 2);	/* truncate hash */
#else
			memcpy(vidm + 2, hash, MD5_DIGEST_SIZE);
			memset(vidm + 2 + MD5_DIGEST_SIZE, '\0',
			       FSWAN_VID_SIZE - (2 + MD5_DIGEST_SIZE));	/* pad hash */
#endif
			for (i = 2; i < FSWAN_VID_SIZE; i++) {
				vidm[i] &= 0x7f;
				vidm[i] |= 0x40;
			}
			vid->vid_len = FSWAN_VID_SIZE;
#undef FSWAN_VID_SIZE
		}

		if (vid->descr == NULL) {
			/** Find something to display **/
			vid->descr = vid->data;
		}
#if 0
		DBG_log("init_vendorid: %d [%s]",
			vid->id,
			vid->descr == NULL ? vid->descr : "");
		if (vid->vid)
			DBG_dump("VID:", vid->vid, vid->vid_len);
#endif
	}
}
コード例 #24
0
ファイル: packet.c プロジェクト: Biamp-Systems/mb-linux
/* print a host struct
 *
 * This code assumes that the network and host structure
 * members have the same alignment and size!  This requires
 * that all padding be explicit.
 */
void
DBG_print_struct(const char *label, const void *struct_ptr
, struct_desc *sd, bool len_meaningful)
{
    bool immediate = FALSE;
    const u_int8_t *inp = struct_ptr;
    field_desc *fp;

    DBG_log("%s%s:", label, sd->name);

    for (fp = sd->fields; fp->field_type != ft_end; fp++) {
	int i = fp->size;
	u_int32_t n = 0;

	switch (fp->field_type) {
	case ft_mbz:	/* must be zero */
	    inp += i;
	    break;
	case ft_nat:	/* natural number (may be 0) */
	case ft_len:	/* length of this struct and any following crud */
	case ft_lv:	/* length/value field of attribute */
	case ft_enum:	/* value from an enumeration */
	case ft_loose_enum:	/* value from an enumeration with only some names known */
	case ft_af_enum:	/* Attribute Format + value from an enumeration */
	case ft_set:	/* bits representing set */
	    switch (i) {
	    case 8/BITS_PER_BYTE:
		n = *(const u_int8_t *)inp;
		break;
	    case 16/BITS_PER_BYTE:
		n = *(const u_int16_t *)inp;
		break;
	    case 32/BITS_PER_BYTE:
		n = *(const u_int32_t *)inp;
		break;
	    default:
		impossible();
	    }
	    switch (fp->field_type) {
	    case ft_len:	/* length of this struct and any following crud */
	    case ft_lv:		/* length/value field of attribute */
		if (!immediate && !len_meaningful)
		    break;
		/* FALL THROUGH */
	    case ft_nat:	/* natural number (may be 0) */
		DBG_log("   %s: %lu", fp->name, (unsigned long)n);
		break;
	    case ft_af_enum:	/* Attribute Format + value from an enumeration */
		if ((n & ISAKMP_ATTR_AF_MASK) == ISAKMP_ATTR_AF_TV)
		    immediate = TRUE;
		/* FALL THROUGH */
	    case ft_enum:	/* value from an enumeration */
	    case ft_loose_enum:	/* value from an enumeration with only some names known */
		DBG_log("   %s: %s", fp->name, enum_show(fp->desc, n));
		break;
	    case ft_set:	/* bits representing set */
		DBG_log("   %s: %s", fp->name, bitnamesof(fp->desc, n));
		break;
	    default:
		impossible();
		break;
	    }
	    inp += i;
	    break;

	case ft_raw:	/* bytes to be left in network-order */
	    {
		char m[50];	/* arbitrary limit on name width in log */

		snprintf(m, sizeof(m), "   %s:", fp->name);
		DBG_dump(m, inp, i);
		inp += i;
	    }
	    break;
	default:
	    impossible();
	    break;
	}
    }
}
コード例 #25
0
ファイル: crypt_ke.c プロジェクト: lkundrak/libreswan
/* MUST BE THREAD-SAFE */
void calc_ke(struct pluto_crypto_req *r)
{
	SECKEYDHParams dhp;
	PK11SlotInfo *slot = NULL;
	SECKEYPrivateKey *privk;
	SECKEYPublicKey *pubk;
	struct pcr_kenonce *kn = &r->pcr_d.kn;
	const struct oakley_group_desc *group = lookup_group(kn->oakley_group);
	chunk_t base  = mpz_to_n_autosize(group->generator);
	chunk_t prime = mpz_to_n_autosize(group->modulus);

	DBG(DBG_CRYPT, DBG_dump_chunk("NSS: Value of Prime:", prime));
	DBG(DBG_CRYPT, DBG_dump_chunk("NSS: Value of base:", base));

	dhp.prime.data = prime.ptr;
	dhp.prime.len = prime.len;
	dhp.base.data = base.ptr;
	dhp.base.len = base.len;

	slot = PK11_GetBestSlot(CKM_DH_PKCS_KEY_PAIR_GEN,
				lsw_return_nss_password_file_info());
	if (slot == NULL)
		loglog(RC_LOG_SERIOUS, "NSS: slot for DH key gen is NULL");
	passert(slot != NULL);

	for (;;) {
		pubk = NULL;	/* ??? is this needed? Output-only from next call? */
		privk = PK11_GenerateKeyPair(slot, CKM_DH_PKCS_KEY_PAIR_GEN,
					     &dhp, &pubk, PR_FALSE, PR_TRUE,
					     lsw_return_nss_password_file_info());
		if (privk == NULL) {
			loglog(RC_LOG_SERIOUS,
			       "NSS: DH private key creation failed (err %d)",
			       PR_GetError());
		}
		passert(privk != NULL && pubk != NULL);

		if (group->bytes == pubk->u.dh.publicValue.len) {
			DBG(DBG_CRYPT,
			    DBG_log("NSS: generated dh priv and pub keys: %d",
				    pubk->u.dh.publicValue.len));
			break;
		} else {
			DBG(DBG_CRYPT,
			    DBG_log("NSS: generating dh priv and pub keys again"));

			SECKEY_DestroyPrivateKey(privk);
			SECKEY_DestroyPublicKey(pubk);
		}
	}

	kn->secret = privk;
	kn->pubk = pubk;

	ALLOC_WIRE_CHUNK(*kn, gi, pubk->u.dh.publicValue.len);
	{
		unsigned char *gip = WIRE_CHUNK_PTR(*kn, gi);

		memcpy(gip, pubk->u.dh.publicValue.data,
		       pubk->u.dh.publicValue.len);
	}

	DBG(DBG_CRYPT, {
		    DBG_log("NSS: Local DH secret (pointer): %p",
			     kn->secret);
		    DBG_dump("NSS: Public DH value sent(computed in NSS):",
			     WIRE_CHUNK_PTR(*kn, gi),
			     pubk->u.dh.publicValue.len);
	    });
コード例 #26
0
/* Finish (building, sending, accepting response for) PF_KEY message.
 * If response isn't NULL, the response from the kernel will be
 * placed there (and its errno field will not be examined).
 * Returns TRUE iff all appears well.
 */
static bool
finish_pfkey_msg(struct sadb_ext *extensions[SADB_EXT_MAX + 1]
, const char *description
, const char *text_said
, pfkey_buf *response)
{
    struct sadb_msg *pfkey_msg;
    bool success = TRUE;
    int error;

    error = pfkey_msg_build(&pfkey_msg, extensions, EXT_BITS_IN);

    if (error != 0)
    {
	loglog(RC_LOG_SERIOUS, "pfkey_msg_build of %s %s failed, code %d"
	    , description, text_said, error);
	success = FALSE;
    }
    else
    {
	size_t len = pfkey_msg->sadb_msg_len * IPSEC_PFKEYv2_ALIGN;

	DBG(DBG_KLIPS,
	    DBG_log("finish_pfkey_msg: %s message %u for %s %s"
		, sparse_val_show(pfkey_type_names, pfkey_msg->sadb_msg_type)
		, pfkey_msg->sadb_msg_seq
		, description, text_said);
	    DBG_dump(NULL, (void *) pfkey_msg, len));

	if (!no_klips)
	{
	    ssize_t r = write(pfkeyfd, pfkey_msg, len);

	    if (r != (ssize_t)len)
	    {
		if (r < 0)
		{
		    log_errno((e
			, "pfkey write() of %s message %u"
			  " for %s %s failed"
			, sparse_val_show(pfkey_type_names
			    , pfkey_msg->sadb_msg_type)
			, pfkey_msg->sadb_msg_seq
			, description, text_said));
		}
		else
		{
		    loglog(RC_LOG_SERIOUS
			, "ERROR: pfkey write() of %s message %u"
			  " for %s %s truncated: %ld instead of %ld"
			, sparse_val_show(pfkey_type_names
			    , pfkey_msg->sadb_msg_type)
			, pfkey_msg->sadb_msg_seq
			, description, text_said
			, (long)r, (long)len);
		}
		success = FALSE;

		/* if we were compiled with debugging, but we haven't already
		 * dumped the KLIPS command, do so.
		 */
#ifdef DEBUG
		if ((cur_debugging & DBG_KLIPS) == 0)
		    DBG_dump(NULL, (void *) pfkey_msg, len);
#endif
	    }
	    else
	    {
		/* Check response from KLIPS.
		 * It ought to be an echo, perhaps with additional info.
		 * If the caller wants it, response will point to space.
		 */
		pfkey_buf b;
		pfkey_buf *bp = response != NULL? response : &b;

		if (!pfkey_get_response(bp, ((struct sadb_msg *) extensions[0])->sadb_msg_seq))
		{
		    loglog(RC_LOG_SERIOUS
			, "ERROR: no response to our PF_KEY %s message for %s %s"
			, sparse_val_show(pfkey_type_names, pfkey_msg->sadb_msg_type)
			, description, text_said);
		    success = FALSE;
		}
		else if (pfkey_msg->sadb_msg_type != bp->msg.sadb_msg_type)
		{
		    loglog(RC_LOG_SERIOUS
			, "FreeS/WAN ERROR: response to our PF_KEY %s message for %s %s was of wrong type (%s)"
			, sparse_name(pfkey_type_names, pfkey_msg->sadb_msg_type)
			, description, text_said
			, sparse_val_show(pfkey_type_names, bp->msg.sadb_msg_type));
		    success = FALSE;
		}
		else if (response == NULL && bp->msg.sadb_msg_errno != 0)
		{
		    /* KLIPS is signalling a problem */
		    loglog(RC_LOG_SERIOUS
			, "ERROR: PF_KEY %s response for %s %s included errno %u: %s"
			, sparse_val_show(pfkey_type_names, pfkey_msg->sadb_msg_type)
			, description, text_said
			, (unsigned) bp->msg.sadb_msg_errno
			, strerror(bp->msg.sadb_msg_errno));
		    success = FALSE;
		}
	    }
	}
    }

    /* all paths must exit this way to free resources */
    pfkey_extensions_free(extensions);
    pfkey_msg_free(&pfkey_msg);
    return success;
}