Example #1
0
int sc_pkcs15emu_initialize_public_keys(sc_pkcs15_card_t *p15card, p15data_items *items) {
	const pubdata *keys = items->public_keys;
	int i, r;
	if(!keys) return SC_SUCCESS;
	/* set public keys */
	for (i = 0; keys[i].label; i++) {
		r = add_public_key(p15card, &keys[i], 0, 0);
		if (r < 0)
			SC_FUNC_RETURN(p15card->card->ctx, SC_LOG_DEBUG_NORMAL, r);
	}
	return SC_SUCCESS;

}
Example #2
0
int
initialize_client_stage1(ClientRealm* cr, SSL_CTX* ctx, unsigned char* buff, char wanttoexit,
    char ignorePublicKeys)
{
  int n, nlen, elen, len, tmp;
  unsigned int olen;
  X509* server_cert;
  const EVP_MD *md;
  EVP_PKEY* pkey;
  EVP_MD_CTX md_ctx;
  unsigned char *encoded = NULL;
  char b64_encoded[100];
  unsigned char *key_buf = NULL;
  assert((ClientRealm_get_tunnelType(cr) == 0) || (ClientRealm_get_tunnelType(cr) == 1));
  switch (ClientRealm_get_tunnelType(cr)) {
    case 0: {
      if (ip_connect(&tmp, ClientRealm_get_serverName(cr),
            ClientRealm_get_managePort(cr),
            ClientRealm_get_ipFamily(cr),
            ClientRealm_get_localName(cr),
            ClientRealm_get_localPort(cr))) {
#ifdef AF_INET6
        aflog(LOG_T_INIT, LOG_I_CRIT,
            "tcp_connect_%s error for %s, %s",
            (ClientRealm_get_ipFamily(cr) & 0x02) ?
              "ipv4":(ClientRealm_get_ipFamily(cr) & 0x04) ?
                "ipv6":"unspec", ClientRealm_get_serverName(cr), ClientRealm_get_managePort(cr));
#else
        aflog(LOG_T_INIT, LOG_I_CRIT,
            "tcp_connect error for %s, %s", ClientRealm_get_serverName(cr), ClientRealm_get_managePort(cr));
#endif
        if (wanttoexit) {
          exit(1);
        }
        else {
          return 1;
        }
      } 
      SslFd_set_fd(ClientRealm_get_masterSslFd(cr), tmp);
      break;
            }
#ifdef HAVE_LIBPTHREAD 
    case 1: {
      if (initialize_http_proxy_client(&tmp, cr, ctx)) {
#ifdef AF_INET6
        aflog(LOG_T_INIT, LOG_I_CRIT,
            "http_proxy_connect_%s error for %s, %s (proxy: %s, %s)",
            (ClientRealm_get_ipFamily(cr) & 0x02) ?
              "ipv4":(ClientRealm_get_ipFamily(cr) & 0x04) ?
                "ipv6":"unspec", ClientRealm_get_serverName(cr),
                ClientRealm_get_managePort(cr),
                HttpProxyOptions_get_proxyname(ClientRealm_get_httpProxyOptions(cr)),
                HttpProxyOptions_get_proxyport(ClientRealm_get_httpProxyOptions(cr)));
#else 
        aflog(LOG_T_INIT, LOG_I_CRIT,
            "http_proxy_connect error for %s, %s (proxy: %s, %s)", ClientRealm_get_serverName(cr),
            ClientRealm_get_managePort(cr),
            HttpProxyOptions_get_proxyname(ClientRealm_get_httpProxyOptions(cr)),
            HttpProxyOptions_get_proxyport(ClientRealm_get_httpProxyOptions(cr)));
#endif 
        if (wanttoexit) {
          exit(1);
        }
        else {
          return 1;
        }
      }
      SslFd_set_fd(ClientRealm_get_masterSslFd(cr), tmp);
      break;
            }
#endif
    default: {
               aflog(LOG_T_INIT, LOG_I_CRIT,
                   "Unknown tunnel type");
               if (wanttoexit) {
                 exit(1);
               }
               else {
                 return 1;
               }
               break;
             }
  }
  
  SslFd_set_ssl(ClientRealm_get_masterSslFd(cr), SSL_new(ctx));
  if (SSL_set_fd(SslFd_get_ssl(ClientRealm_get_masterSslFd(cr)),
        SslFd_get_fd(ClientRealm_get_masterSslFd(cr))) != 1) {
    aflog(LOG_T_INIT, LOG_I_CRIT,
        "Problem with initializing ssl... exiting");
    if (wanttoexit) {
      exit(1);
    }
    else {
      close(SslFd_get_fd(ClientRealm_get_masterSslFd(cr)));
      return 2;
    }
  }

  alarm(60);
  
  aflog(LOG_T_INIT, LOG_I_INFO,
      "Trying SSL_connect");
  if ((n = SSL_connect(SslFd_get_ssl(ClientRealm_get_masterSslFd(cr)))) == 1) {
    if ((server_cert = SSL_get_peer_certificate(SslFd_get_ssl(ClientRealm_get_masterSslFd(cr)))) == NULL) {
      aflog(LOG_T_MAIN, LOG_I_CRIT,
          "Server did not present a certificate... exiting");
      exit(1);
    }
    /* FIXME: change almost everything here */
    pkey = X509_get_pubkey(server_cert);
    if (pkey == NULL) {
      aflog(LOG_T_MAIN, LOG_I_CRIT,
          "Server's public key is invalid... exiting");
      exit(1);
    }
    nlen = BN_num_bytes(pkey->pkey.rsa->n);
    elen = BN_num_bytes(pkey->pkey.rsa->e);
    len = nlen + elen;
    key_buf = malloc(len);
    if (key_buf == NULL) {
      aflog(LOG_T_MAIN, LOG_I_CRIT,
          "Cannot allocate memory for server's public key checking... exiting");
      exit(1);
    }
    BN_bn2bin(pkey->pkey.rsa->n, key_buf);
    BN_bn2bin(pkey->pkey.rsa->e, key_buf + nlen);
    md = EVP_md5();
    EVP_DigestInit(&md_ctx, md);
    EVP_DigestUpdate(&md_ctx, key_buf, len);
    encoded = calloc(1, EVP_MAX_MD_SIZE+1);
    if (encoded == NULL) {
      aflog(LOG_T_MAIN, LOG_I_CRIT,
          "Cannot allocate memory for server's public key checking... exiting");
      exit(1);
    }
    EVP_DigestFinal(&md_ctx, encoded, &olen);

    if (b64_ntop(encoded, olen, b64_encoded, 100) == -1) {
      aflog(LOG_T_MAIN, LOG_I_CRIT,
          "Problem with base64 encoding... exiting");
      exit(1);
    }
    
    switch (check_public_key(get_store_filename(), ClientRealm_get_serverName(cr), b64_encoded)) {
      case SSL_PUBLIC_KEY_VALID:
        /* public key is ok - do nothing */
        break;
      case SSL_PUBLIC_KEY_NOT_KNOWN:
        aflog(LOG_T_MAIN, LOG_I_WARNING,
            "WARNING: implicitly added new server's public key to the list of known hosts");
        add_public_key(get_store_filename(), ClientRealm_get_serverName(cr), b64_encoded);
        break;
      default:
        if (ignorePublicKeys) {
          aflog(LOG_T_MAIN, LOG_I_WARNING,
              "WARNING: Invalid server's public key... ignoring");
        }
        else {
          aflog(LOG_T_MAIN, LOG_I_CRIT,
              "Invalid server's public key... exiting");
          aflog(LOG_T_MAIN, LOG_I_CRIT,
              "Please delete conflicting entry in %s or use '--ignorepkeys' option",
              get_store_filename());
          exit(1);
        }
    }

    memset(key_buf, 0, len);
    free(key_buf);
    free(encoded);

    aflog(LOG_T_INIT, LOG_I_INFO,
        "SSL_connect successful");
  }
  else {
    alarm(0);
    aflog(LOG_T_INIT, LOG_I_CRIT,
        "SSL_connect has failed (%d | %d)... exiting", n,
        SSL_get_error(SslFd_get_ssl(ClientRealm_get_masterSslFd(cr)), n));
    if (wanttoexit) {
      exit(1);
    }
    else {
      close(SslFd_get_fd(ClientRealm_get_masterSslFd(cr)));
      return 3;
    }
  }
  alarm(0);

  buff[0] = AF_S_LOGIN;
  buff[1] = ClientRealm_get_password(cr)[0];
  buff[2] = ClientRealm_get_password(cr)[1];
  buff[3] = ClientRealm_get_password(cr)[2];
  buff[4] = ClientRealm_get_password(cr)[3];

  return 0;
}
Example #3
0
static void key_add_request(const struct whack_message *msg)
{
	struct id keyid;
	err_t ugh = atoid(msg->keyid, &keyid, FALSE, FALSE);

	if (ugh != NULL) {
		loglog(RC_BADID, "bad --keyid \"%s\": %s", msg->keyid, ugh);
	} else {
		if (!msg->whack_addkey)
			delete_public_keys(&pluto_pubkeys, &keyid,
					   msg->pubkey_alg);

		if (msg->keyval.len == 0) {
			struct key_add_common *oc =
				alloc_thing(struct key_add_common,
					    "key add common things");
			enum key_add_attempt kaa;

			/* initialize state shared by queries */
			oc->refCount = 0;
			oc->whack_fd = dup_any(whack_log_fd);
			oc->success = FALSE;

			for (kaa = ka_TXT; kaa != ka_roof; kaa++) {
				struct key_add_continuation *kc =
					alloc_thing(
						struct key_add_continuation,
						"key add continuation");

				oc->diag[kaa] = NULL;
				oc->refCount++;
				kc->common = oc;
				kc->lookingfor = kaa;
				switch (kaa) {
				case ka_TXT:
					ugh = start_adns_query(&keyid,
							       &keyid, /* same */
							       ns_t_txt,
							       key_add_continue,
							       &kc->ac);
					break;
#ifdef USE_KEYRR
				case ka_KEY:
					ugh = start_adns_query(&keyid,
							       NULL,
							       ns_t_key,
							       key_add_continue,
							       &kc->ac);
					break;
#endif                                                  /* USE_KEYRR */
				default:
					bad_case(kaa);  /* suppress gcc warning */
				}
				if (ugh != NULL) {
					oc->diag[kaa] = clone_str(ugh,
								  "early key add failure");
					oc->refCount--;
				}
			}

			/* Done launching queries.
			 * Handle total failure case.
			 */
			key_add_merge(oc, &keyid);
		} else {
			ugh = add_public_key(&keyid, DAL_LOCAL,
					     msg->pubkey_alg,
					     &msg->keyval, &pluto_pubkeys);
			if (ugh != NULL)
				loglog(RC_LOG_SERIOUS, "%s", ugh);
		}
	}
Example #4
0
/* Handle a kernel request. Supposedly, there's a message in
 * the kernelsock socket.
 */
void
whack_handle(int whackctlfd)
{
    struct whack_message msg;
    struct sockaddr_un whackaddr;
    int whackaddrlen = sizeof(whackaddr);
    int whackfd = accept(whackctlfd, (struct sockaddr *)&whackaddr, &whackaddrlen);
    ssize_t n;

    if (whackfd < 0)
    {
	log_errno((e, "accept() failed in whack_handle()"));
	return;
    }
    n = read(whackfd, &msg, sizeof(msg));
    if (n == -1)
    {
	log_errno((e, "read() failed in whack_handle()"));
	close(whackfd);
	return;
    }

    whack_log_fd = whackfd;

    /* sanity check message */
    {
	err_t ugh = NULL;

	next_str = msg.string;
	str_roof = (char *)&msg + n;

	if (next_str > str_roof)
	{
	    ugh = builddiag("truncated message from whack: got %d bytes; expected %d.  Message ignored."
		, n, (int) sizeof(msg));
	}
	else if (msg.magic != WHACK_MAGIC)
	{
	    ugh = builddiag("message from whack has bad magic %d; should be %d; probably wrong version.  Message ignored"
		, msg.magic, WHACK_MAGIC);
	}
	else if (!unpack_str(&msg.name)		/* string 1 */
	|| !unpack_str(&msg.left.id)		/* string 2 */
	|| !unpack_str(&msg.left.cert)		/* string 3 */
	|| !unpack_str(&msg.left.updown)	/* string 4 */
#ifdef VIRTUAL_IP
	|| !unpack_str(&msg.left.virt)
#endif
	|| !unpack_str(&msg.right.id)		/* string 5 */
	|| !unpack_str(&msg.right.cert)		/* string 6 */	
	|| !unpack_str(&msg.right.updown)	/* string 7 */
#ifdef VIRTUAL_IP
	|| !unpack_str(&msg.right.virt)
#endif
	|| !unpack_str(&msg.keyid)		/* string 8 */
	|| !unpack_str(&msg.ike)		/* string 9 */
	|| !unpack_str(&msg.esp)		/* string 10 */	
	|| !unpack_str(&msg.dnshostname)	/* string 11 */
	|| str_roof - next_str != (ptrdiff_t)msg.keyval.len)	/* check chunk */
	{
	    ugh = "message from whack contains bad string";
	}
	else
	{
	    msg.keyval.ptr = next_str;	/* grab chunk */
	}

	if (ugh != NULL)
	{
	    loglog(RC_BADWHACKMESSAGE, "%s", ugh);
	    whack_log_fd = NULL_FD;
	    close(whackfd);
	    return;
	}
    }

    if (msg.whack_options)
    {
#ifdef DEBUG
	if (msg.name == NULL)
	{
	    /* we do a two-step so that if either old or new would
	     * cause the message to print, it will be printed.
	     */
	    cur_debugging |= msg.debugging;
	    DBG(DBG_CONTROL
		, DBG_log("base debugging = %s"
		    , bitnamesof(debug_bit_names, msg.debugging)));
	    cur_debugging = base_debugging = msg.debugging;
	}
	else if (!msg.whack_connection)
	{
	    struct connection *c = con_by_name(msg.name, TRUE);

	    if (c != NULL)
	    {
		c->extra_debugging = msg.debugging;
		DBG(DBG_CONTROL
		    , DBG_log("\"%s\" extra_debugging = %s"
			, c->name
			, bitnamesof(debug_bit_names, c->extra_debugging)));
	    }
	}
#endif
    }

    /* Deleting combined with adding a connection works as replace.
     * To make this more useful, in only this combination,
     * delete will silently ignore the lack of the connection.
     */
    if (msg.whack_delete)
    {
	struct connection *c = con_by_name(msg.name, !msg.whack_connection);

	/* note: this is a "while" because road warrior
	 * leads to multiple connections with the same name.
	 */
	for (; c != NULL; c = con_by_name(msg.name, FALSE))
	    delete_connection(c);
    }

    if (msg.whack_deletestate)
    {
	struct state *st = state_with_serialno(msg.whack_deletestateno);

	if (st == NULL)
	{
	    loglog(RC_UNKNOWN_NAME, "no state #%lu to delete"
		, msg.whack_deletestateno);
	}
	else
	{
	    delete_state(st);
	}
    }

    if (msg.whack_connection)
	add_connection(&msg);

    /* process "listen" before any operation that could require it */
    if (msg.whack_listen)
    {
	log("listening for IKE messages");
	listening = TRUE;
	find_ifaces();
	load_preshared_secrets();
    }
    if (msg.whack_unlisten)
    {
	log("no longer listening for IKE messages");
	listening = FALSE;
    }

    if (msg.whack_reread & REREAD_SECRETS)
    {
	load_preshared_secrets();
    }

   if (msg.whack_reread & REREAD_MYCERT)
    {
	load_mycert();
    }

   if (msg.whack_reread & REREAD_CACERTS)
    {
	load_cacerts();
    }

   if (msg.whack_reread & REREAD_CRLS)
    {
	load_crls();
    }

   if (msg.whack_list & LIST_PUBKEYS)
    {
	list_public_keys(msg.whack_utc);
    }

    if (msg.whack_list & LIST_CERTS)
    {
	list_certs(msg.whack_utc);
    }

    if (msg.whack_list & LIST_CACERTS)
    {
	list_cacerts(msg.whack_utc);
    }

    if (msg.whack_list & LIST_CRLS)
    {
	list_crls(msg.whack_utc);
    }

    if (msg.whack_key)
    {
	/* add a public key */
	struct id keyid;
	err_t ugh = atoid(msg.keyid, &keyid);

	if (ugh != NULL)
	{
	    loglog(RC_BADID, "bad --keyid \"%s\": %s", msg.keyid, ugh);
	}
	else
	{
	    if (!msg.whack_addkey)
		delete_public_keys(&keyid, msg.pubkey_alg);

	    if (msg.keyval.len == 0)
	    {
		struct key_add_continuation *kc
		    = alloc_thing(struct key_add_continuation
			, "key add continuation");
		int wfd = dup_any(whackfd);

		kc->whack_fd = wfd;
		ugh = start_adns_query(&keyid
		    , NULL
		    , T_KEY
		    , key_add_continue
		    , &kc->ac);

		if (ugh != NULL)
		{
		    key_add_ugh(&keyid, ugh);
		    close_any(wfd);
		}
	    }
	    else
	    {
		ugh = add_public_key(&keyid, DAL_LOCAL, msg.pubkey_alg
		    , &msg.keyval, &pubkeys);
		if (ugh != NULL)
		    loglog(RC_LOG_SERIOUS, "%s", ugh);
	    }
	}
    }