示例#1
0
文件: id.c 项目: dotmark/libreswan
/* compare two struct id values, DNs can contain wildcards */
bool match_id(const struct id *a, const struct id *b, int *wildcards)
{

	bool match;

	if (b->kind == ID_NONE) {
		*wildcards = MAX_WILDCARDS;
		match = TRUE;
	} else if (a->kind != b->kind) {
		match = FALSE;
	} else if (a->kind == ID_DER_ASN1_DN) {
		match = match_dn(a->name, b->name, wildcards);
	} else {
		*wildcards = 0;
		match = same_id(a, b);
	}

	DBG(DBG_CONTROLMORE, {
			char abuf[IDTOA_BUF];
			char bbuf[IDTOA_BUF];
			idtoa(a, abuf, IDTOA_BUF);
			idtoa(b, bbuf, IDTOA_BUF);
			DBG_log("   match_id a=%s", abuf);
			DBG_log("            b=%s", bbuf);
			DBG_log("   results  %s", match ? "matched" : "fail");
		});
示例#2
0
struct secret *pick_key(struct secret *host_secrets
			, char *idname)
{
    struct id id;
    struct secret *s;
    err_t e;

    e = atoid(idname, &id, FALSE);
    if(e) {
	printf("%s: key '%s' is invalid\n", progname, idname);
	exit(4);
    }

    s = osw_find_secret_by_id(host_secrets, PPK_RSA
			      , &id, NULL, TRUE /* asymmetric */);
    
    if(s==NULL) {
	char abuf[IDTOA_BUF];
	idtoa(&id, abuf, IDTOA_BUF);
	printf("%s: can not find key: %s (%s)\n", progname, idname, abuf);
	exit(5);
    }

    return s;
}
示例#3
0
void show_myid_status(void)
{
	char idstr[IDTOA_BUF];

	(void)idtoa(&myids[myid_state], idstr, sizeof(idstr));
	whack_log(RC_COMMENT, "myid = %s", idstr);
}
示例#4
0
static void key_add_ugh(const struct id *keyid, err_t ugh)
{
	char name[IDTOA_BUF];   /* longer IDs will be truncated in message */

	(void)idtoa(keyid, name, sizeof(name));
	loglog(RC_NOKEY,
	       "failure to fetch key for %s from DNS: %s", name, ugh);
}
示例#5
0
static void calc_myid_str(enum myid_state s)
{
	/* preformat the ID name */
	char buf[IDTOA_BUF];

	idtoa(&myids[s], buf, IDTOA_BUF);
	/* replace() uses pfreeany() */
	replace(myid_str[s], clone_str(buf, "myid string"));
}
void block_peer_log(const char *msg, block_peer *peer)
{
    char peer_ip_str[IDTOA_BUF];
    struct id id;

    iptoid(&peer->ip, &id);
    idtoa(&id, peer_ip_str, IDTOA_BUF);
    loglog(RC_LOG_SERIOUS, msg, peer_ip_str);
}
示例#7
0
static void print(struct private_key_stuff *pks,
		  int count, struct id *id, bool disclose)
{
	char idb[IDTOA_BUF] = "n/a";
	if (id) {
		idtoa(id, idb, IDTOA_BUF);
	}

	char pskbuf[128] = "";
	if (pks->kind == PPK_PSK || pks->kind == PPK_XAUTH) {
		datatot(pks->u.preshared_secret.ptr,
			pks->u.preshared_secret.len,
			'x', pskbuf, sizeof(pskbuf));
	}

	if (count) {
		/* ipsec.secrets format */
		printf("%d(%d): ", pks->line, count);
	} else {
		/* NSS format */
		printf("<%2d> ", pks->line);
	}

	switch (pks->kind) {
	case PPK_PSK:
		printf("PSK keyid: %s\n", idb);
		if (disclose)
			printf("    psk: \"%s\"\n", pskbuf);
		break;

	case PPK_RSA: {
		printf("RSA");
		char *keyid = pks->u.RSA_private_key.pub.keyid;
		printf(" keyid: %s", keyid[0] ? keyid : "<missing-pubkey>");
		if (id) {
			printf(" id: %s", idb);
		}
		char *ckaid = ckaid_as_string(pks->u.RSA_private_key.pub.ckaid);
		printf(" ckaid: %s\n", ckaid);
		pfree(ckaid);
		break;
	}

	case PPK_XAUTH:
		printf("XAUTH keyid: %s\n", idb);
		if (disclose)
			printf("    xauth: \"%s\"\n", pskbuf);
		break;
	case PPK_NULL:
		/* can't happen but the compiler does not know that */
		printf("NULL authentication -- cannot happen: %s\n", idb);
		abort();
	}
}
示例#8
0
int print_key(struct secret *secret
	      , struct private_key_stuff *pks
	      , void *uservoid, bool disclose)
{
    int lineno = osw_get_secretlineno(secret);
    struct id_list *l = osw_get_idlist(secret);
    char idb[IDTOA_BUF];
    int count=1;

    char pskbuf[128];

    if(pks->kind == PPK_PSK || pks->kind==PPK_XAUTH) {
	datatot(pks->u.preshared_secret.ptr,
		pks->u.preshared_secret.len,
		'x', pskbuf, sizeof(pskbuf));
    }

    while(l) {
	idtoa(&l->id, idb, IDTOA_BUF);

	switch(pks->kind) {
	case PPK_PSK:
	    printf("%d(%d): PSK keyid: %s\n", lineno, count, idb);
	    if(disclose) printf("    psk: \"%s\"\n", pskbuf);
	    break;
	    
	case PPK_RSA:
	    printf("%d(%d): RSA keyid: %s with id: %s\n", lineno, count, pks->u.RSA_private_key.pub.keyid,idb);
	    break;
	    
	case PPK_XAUTH:
	    printf("%d(%d): XAUTH keyid: %s\n", lineno, count, idb);
	    if(disclose) printf("    xauth: \"%s\"\n", pskbuf);
	    break;
	    
	case PPK_PIN:
	    printf("%d:(%d) PIN key-type not yet supported for id: %s\n", lineno, count, idb);
	    break;
	}
	
	l=l->next;
	count++;
    }
    
    return 1;
}
示例#9
0
/** Lookup information about the hostpair, and set things like bandwidth
 * relative crypto strength, compression and credentials.
 * 
 * @param IPsec Policy Query
 * @return void
 */
static void
info_lookuphostpair(struct ipsec_policy_cmd_query *ipcq)
{
    struct connection *c;
    struct state *p1st, *p2st;


    /* default result: no crypto */
    ipcq->strength  = IPSEC_PRIVACY_NONE;
    ipcq->bandwidth = IPSEC_QOS_WIRESPEED;
    ipcq->credential_count = 0;

#ifdef DEBUG
    {
	char sstr[ADDRTOT_BUF], dstr[ADDRTOT_BUF];

	addrtot(&ipcq->query_local,  0, sstr, sizeof(sstr));
	addrtot(&ipcq->query_remote, 0, dstr, sizeof(dstr));
	DBG_log("info request for %s -> %s", sstr, dstr);
    }
#endif

    /* okay, look up what connection handles this ip pair */

    c = find_connection_for_clients(NULL,
				    &ipcq->query_local,
				    &ipcq->query_remote,
				    ipcq->proto);
    if (c == NULL)
    {
	/* try reversing it */
	c = find_connection_for_clients(NULL,
					&ipcq->query_remote,
					&ipcq->query_local,
					ipcq->proto);
	if (c != NULL)
	{
	    ip_address tmp;
	    /* If it is reversed, swap it */
	    tmp = ipcq->query_local;
	    ipcq->query_local = ipcq->query_remote;
	    ipcq->query_remote = tmp;
	}
    }
    
    if (c == NULL)
    {
#ifdef DEBUG
	DBG_log("no connection found");
#endif
	return;	/* no crypto */
    }

    if (c->newest_ipsec_sa == SOS_NOBODY)
    {
	ip_subnet us, them;

	DBG_log("connection %s found, no ipsec state, looking again", c->name);
	addrtosubnet(&ipcq->query_local, &us);
	addrtosubnet(&ipcq->query_remote, &them);
	c = find_client_connection(c, &us, &them, 0, 0, 0, 0);

	if (c == NULL)
	    return;	/* no crypto */
    }

    DBG_log("connection %s[%ld] with state %u"
	, c->name, c->instance_serial
	, (unsigned int)c->newest_ipsec_sa);

    if (c->newest_ipsec_sa == SOS_NOBODY)
	return;	/* no crypto */

    /* we found a connection, try to lookup the state */
    p2st = state_with_serialno(c->newest_ipsec_sa);

    p1st = find_phase1_state(c, ISAKMP_SA_ESTABLISHED_STATES);

    if (p1st == NULL || p2st == NULL)
    {
	DBG_log("connection %s[%ld] has missing states %s %s"
	    , c->name, c->instance_serial
	    , (p1st ? "phase1" : "")
	    , (p2st ? "phase1" : ""));
	return;	/* no crypto */
    }

    /* if we have AH present, then record minimal info */
    if (p2st->st_ah.present)
    {
	ipcq->strength = IPSEC_PRIVACY_INTEGRAL;
	ipcq->auth_detail = p2st->st_esp.attrs.transattrs.integ_hash;
    }

    if (p2st->st_esp.present)
    {
	/*
	 * XXX-mcr Please do not shout at me about relative strengths
	 *         here. I'm not a cryptographer. I just diddle bits.
	 */
	switch (p2st->st_esp.attrs.transattrs.encrypt)
	{
	case ESP_NULL:
	    /* actually, do not change it if we set it from AH */
	    break;

	case ESP_DES:
	case ESP_DES_IV64:
	case ESP_DES_IV32:
	case ESP_RC4:
	    ipcq->strength = IPSEC_PRIVACY_ROT13;
	    break;
	    
	case ESP_RC5:
	case ESP_IDEA:
	case ESP_CAST:
	case ESP_BLOWFISH:
	case ESP_3DES:
	    ipcq->strength = IPSEC_PRIVACY_PRIVATE;
	    ipcq->bandwidth = IPSEC_QOS_VOIP;
	    break;

	case ESP_3IDEA:
	    ipcq->strength = IPSEC_PRIVACY_STRONG;
	    ipcq->bandwidth = IPSEC_QOS_INTERACTIVE;
	    break;

	case ESP_AES:
	    ipcq->strength = IPSEC_PRIVACY_STRONG;
	    ipcq->bandwidth = IPSEC_QOS_FTP;
	    break;
	}
	ipcq->esp_detail = p2st->st_esp.attrs.transattrs.encrypt;
    }

    if (p2st->st_ipcomp.present)
	ipcq->comp_detail = p2st->st_esp.attrs.transattrs.encrypt;

    /* now! the credentails that were used */
    /* for the moment we only have 1 credential, the DNS name,
     * because the DNS servers do not return the chain of SIGs yet
     */

    if(!c->spd.this.key_from_DNS_on_demand)
    {
	/* the key didn't come from the DNS in some way,
	 * so it must have been loaded locally.
	 */
	ipcq->credential_count = 1;
	ipcq->credentials[0].ii_type   = c->spd.this.id.kind;
	ipcq->credentials[0].ii_format = CERT_RAW_RSA;
    }
	
#if 0
    switch (c->spd.id.kind)
    {
    case ID_IPV4_ADDR:
    }
    if (c->gw_info == NULL)
    {
	plog("rcv_info: connection %s had NULL gw_info.", c->name);
	return
    }
#endif

    ipcq->credential_count = 1;

    /* pull credentials out of gw_info */
    
    switch (p1st->st_peer_pubkey->dns_auth_level)
    {
    case DAL_UNSIGNED:
    case DAL_NOTSEC:
	/* these seem to be the same for this purpose */
	ipcq->credentials[0].ii_type   = p1st->st_peer_pubkey->id.kind;
	ipcq->credentials[0].ii_type   = CERT_NONE;
	idtoa(&p1st->st_peer_pubkey->id
	    , ipcq->credentials[0].ii_credential.ipsec_dns_signed.fqdn
	    , sizeof(ipcq->credentials[0].ii_credential.ipsec_dns_signed.fqdn));
	break;
	
    case DAL_SIGNED:
	ipcq->credentials[0].ii_type   = p1st->st_peer_pubkey->id.kind;
	ipcq->credentials[0].ii_format = CERT_DNS_SIGNED_KEY;
	idtoa(&p1st->st_peer_pubkey->id
	    , ipcq->credentials[0].ii_credential.ipsec_dns_signed.fqdn
	    , sizeof(ipcq->credentials[0].ii_credential.ipsec_dns_signed.fqdn));

	if (p1st->st_peer_pubkey->dns_sig != NULL)
	{
	    strncat(ipcq->credentials[0].ii_credential.ipsec_dns_signed.dns_sig
		, p1st->st_peer_pubkey->dns_sig
		, sizeof(ipcq->credentials[0].ii_credential.ipsec_dns_signed.dns_sig) - strlen(ipcq->credentials[0].ii_credential.ipsec_dns_signed.dns_sig -1));
	}
	break;

    case DAL_LOCAL:
	ipcq->credentials[0].ii_type   = p1st->st_peer_pubkey->id.kind;
	ipcq->credentials[0].ii_format = CERT_RAW_RSA;
	idtoa(&p1st->st_peer_pubkey->id
	    , ipcq->credentials[0].ii_credential.ipsec_raw_key.id_name
	    , sizeof(ipcq->credentials[0].ii_credential.ipsec_raw_key.id_name));
	break;
    }
}
示例#10
0
stf_status
ikev2_verify_rsa_sha1(struct state *st
                      , enum phase1_role role
                      , unsigned char *idhash
                      , const struct pubkey_list *keys_from_dns
                      , const struct gw_info *gateways_from_dns
                      , pb_stream *sig_pbs)
{
    struct pubkey_list *p, **pp;
    struct connection *c = st->st_connection;
    int pathlen;

    pp = &pluto_pubkeys;

    {

        DBG(DBG_CONTROL,
            char buf[IDTOA_BUF];
            dntoa_or_null(buf, IDTOA_BUF, c->spd.that.ca, "%any");
            DBG_log("ikev2 verify required CA is '%s'", buf));
    }

    {
        time_t n;
        n = 1438262454;   /* Thu Jul 30 09:21:01 EDT 2015 in seconds */
        list_certs(n);
    }

    for (p = pluto_pubkeys; p != NULL; p = *pp)
    {
        char keyname[IDTOA_BUF];
        struct pubkey *key = p->key;
        pp = &p->next;

        idtoa(&key->id, keyname, IDTOA_BUF);
        DBG_log("checking alg=%d == %d, keyid=%s same_id=%u\n"
                , key->alg, PUBKEY_ALG_RSA
                , keyname
                , same_id(&st->ikev2.st_peer_id, &key->id));
        if (key->alg == PUBKEY_ALG_RSA
                && same_id(&st->ikev2.st_peer_id, &key->id)
                && trusted_ca(key->issuer, c->spd.that.ca, &pathlen))
        {
            time_t tnow;

            DBG(DBG_CONTROL,
                char buf[IDTOA_BUF];
                dntoa_or_null(buf, IDTOA_BUF, key->issuer, "%any");
                DBG_log("key issuer CA is '%s'", buf));

            /* check if found public key has expired */
            time(&tnow);
            if (key->until_time != UNDEFINED_TIME && key->until_time < tnow)
            {
                loglog(RC_LOG_SERIOUS,
                       "cached RSA public key has expired and has been deleted");
                *pp = free_public_keyentry(p);
                continue; /* continue with next public key */
            }

            return STF_OK;
        }
    }
示例#11
0
static stf_status aggr_inI1_outR1_common(struct msg_digest *md,
					 int authtype)
{
	/* With Aggressive Mode, we get an ID payload in this, the first
	 * message, so we can use it to index the preshared-secrets
	 * when the IP address would not be meaningful (i.e. Road
	 * Warrior).  So our first task is to unravel the ID payload.
	 */
	struct state *st;
	struct payload_digest *const sa_pd = md->chain[ISAKMP_NEXT_SA];
	struct connection *c = find_host_connection(&md->iface->ip_addr,
						    md->iface->port,
						    &md->sender,
						    md->sender_port, LEMPTY);

#if 0
	if (c == NULL && md->iface->ike_float) {
		c = find_host_connection(&md->iface->addr,
					 pluto_nat_port,
					 &md->sender, md->sender_port, LEMPTY);
	}
#endif

	if (c == NULL) {
		/* see if a wildcarded connection can be found */
		pb_stream pre_sa_pbs = sa_pd->pbs;
		lset_t policy = preparse_isakmp_sa_body(&pre_sa_pbs) |
				POLICY_AGGRESSIVE;

		c = find_host_connection(&md->iface->ip_addr, pluto_port,
					 (ip_address*)NULL, md->sender_port,
					 policy);
		if (c == NULL || (c->policy & POLICY_AGGRESSIVE) == 0) {
			ipstr_buf b;

			loglog(RC_LOG_SERIOUS, "initial Aggressive Mode message from %s"
			       " but no (wildcard) connection has been configured%s%s",
			       ipstr(&md->sender, &b),
			       (policy != LEMPTY) ? " with policy=" : "",
			       (policy != LEMPTY) ?
			       bitnamesof(sa_policy_bit_names, policy) : "");
			/* XXX notification is in order! */
			return STF_IGNORE;
		}
		/* Create a temporary connection that is a copy of this one.
		 * His ID isn't declared yet.
		 */
		c = rw_instantiate(c, &md->sender, NULL, NULL);
	}

	/* Set up state */
	cur_state = md->st = st = new_state();  /* (caller will reset cur_state) */
	st->st_connection = c;
	st->st_remoteaddr = md->sender;
	st->st_remoteport = md->sender_port;
	st->st_localaddr  = md->iface->ip_addr;
	st->st_localport  = md->iface->port;
	st->st_interface  = md->iface;
	change_state(st, STATE_AGGR_R1);

	/* until we have clue who this is, then be conservative about allocating
	 * them any crypto bandwidth
	 */
	st->st_import = pcim_stranger_crypto;

	st->st_policy |= POLICY_AGGRESSIVE;

	st->st_oakley.auth = authtype;

	if (!ikev1_decode_peer_id(md, FALSE, TRUE)) {
		char buf[IDTOA_BUF];
		ipstr_buf b;

		(void) idtoa(&st->st_connection->spd.that.id, buf,
			     sizeof(buf));
		loglog(RC_LOG_SERIOUS,
		       "initial Aggressive Mode packet claiming to be from %s"
		       " on %s but no connection has been authorized",
		       buf, ipstr(&md->sender, &b));
		/* XXX notification is in order! */
		return STF_FAIL + INVALID_ID_INFORMATION;
	}

	c = st->st_connection;

	extra_debugging(c);
	st->st_try = 0;                                 /* Not our job to try again from start */
	st->st_policy = c->policy & ~POLICY_IPSEC_MASK; /* only as accurate as connection */

	memcpy(st->st_icookie, md->hdr.isa_icookie, COOKIE_SIZE);
	get_cookie(FALSE, st->st_rcookie, COOKIE_SIZE, &md->sender);

	insert_state(st); /* needs cookies, connection, and msgid (0) */

	st->st_doi = ISAKMP_DOI_IPSEC;
	st->st_situation = SIT_IDENTITY_ONLY; /* We only support this */

	{
		ipstr_buf b;

		libreswan_log("responding to Aggressive Mode, state #%lu, connection \"%s\" from %s",
			st->st_serialno, st->st_connection->name,
			ipstr(&c->spd.that.host_addr, &b));
	}

	merge_quirks(st, md);

	set_nat_traversal(st, md);

	/* save initiator SA for HASH */
	clonereplacechunk(st->st_p1isa, sa_pd->pbs.start,
		pbs_room(&sa_pd->pbs), "sa in aggr_inI1_outR1()");

	/*
	 * parse_isakmp_sa picks the right group, which we need to know
	 * before we do any calculations. We will call it again to have it
	 * emit the winning SA into the output.
	 */
	/* SA body in */
	{
		pb_stream sabs = sa_pd->pbs;

		RETURN_STF_FAILURE(parse_isakmp_sa_body(&sabs,
							&sa_pd->payload.sa,
							NULL, FALSE, st));
	}

	/* KE in */
	RETURN_STF_FAILURE(accept_KE(&st->st_gi, "Gi", st->st_oakley.group,
				     &md->chain[ISAKMP_NEXT_KE]->pbs));

	/* Ni in */
	RETURN_STF_FAILURE(accept_v1_nonce(md, &st->st_ni, "Ni"));

	{
		struct ke_continuation *ke = alloc_thing(
			struct ke_continuation,
			"outI2 KE");

		ke->ke_md = md;
		set_suspended(st, md);

		if (!st->st_sec_in_use) {
			/* need to calculate KE and Nonce */
			pcrc_init(&ke->ke_pcrc, aggr_inI1_outR1_continue1);
			return build_ke(&ke->ke_pcrc, st, st->st_oakley.group,
					st->st_import);
		} else {
			/* KE and Nonce calculated */
			ke->ke_pcrc.pcrc_serialno = st->st_serialno;	/* transitional */
			return aggr_inI1_outR1_tail(&ke->ke_pcrc, NULL);
		}
	}
}