Пример #1
0
/*
 * Close a session.
 */
int
kn_close(int sessid)
{
    struct keynote_session *ks;
    struct assertion *as, *as2;
    int i;

    keynote_errno = 0;
    if ((keynote_current_session == (struct keynote_session *) NULL) ||
	(keynote_current_session->ks_id != sessid))
    {
	keynote_current_session = keynote_find_session(sessid);
	if (keynote_current_session == (struct keynote_session *) NULL)
	{
	    keynote_errno = ERROR_NOTFOUND;
	    return -1;
	}
    }

    ks = keynote_current_session;

    /* Cleanup environment -- no point using kn_cleanup_action_environment() */
    keynote_env_cleanup(ks->ks_env_table, HASHTABLESIZE);
    keynote_env_cleanup(&(ks->ks_env_regex), 1);

    /* Cleanup assertions */
    for (i = 0; i < HASHTABLESIZE; i++)
      for (as = ks->ks_assertion_table[i];
	   as != (struct assertion *) NULL;
	   as = as2)
      {
	  as2 = as->as_next;
	  keynote_free_assertion(as);
      }

    /* Cleanup action authorizers */
    keynote_keylist_free(ks->ks_action_authorizers);

    /* Unlink from chain */
    if (ks->ks_prev == (struct keynote_session *) NULL)
    {
	keynote_sessions[ks->ks_id % SESSIONTABLESIZE] = ks->ks_next;
	if (ks->ks_next != (struct keynote_session *) NULL)
	  ks->ks_next->ks_prev = (struct keynote_session *) NULL;
	
    }
    else
    {
	ks->ks_prev->ks_next = ks->ks_next;
	if (ks->ks_next != (struct keynote_session *) NULL)
	  ks->ks_next->ks_prev = ks->ks_prev;
    }
    
    free(ks);
    keynote_current_session = (struct keynote_session *) NULL;
    return 0;
}
Пример #2
0
/*
 * Verify the signature on an assertion.
 */
int
kn_verify_assertion(char *buf, int len)
{
    struct assertion *as;
    int res;

    keynote_errno = 0;
    as = keynote_parse_assertion(buf, len, ASSERT_FLAG_SIGVER);
    if (as == NULL)
      return -1;

    res = keynote_sigverify_assertion(as);
    keynote_free_assertion(as);
    return res;
}
Пример #3
0
/*
 * Produce the signature for an assertion.
 */
char *
kn_sign_assertion(char *buf, int buflen, char *key, char *sigalg, int vflag)
{
    int i, alg, hashtype, encoding, internalenc;
    struct keynote_deckey dc;
    struct assertion *as;
    char *s, *sig;

    keynote_errno = 0;
    s = NULL;

    if (sigalg == NULL || buf == NULL || key == NULL)
    {
	keynote_errno = ERROR_NOTFOUND;
	return NULL;
    }

    if (sigalg[0] == '\0' || sigalg[strlen(sigalg) - 1] != ':')
    {
	keynote_errno = ERROR_SYNTAX;
	return NULL;
    }

    /* We're using a different format for X509 private keys, so... */
    alg = keynote_get_sig_algorithm(sigalg, &hashtype, &encoding,
				    &internalenc);
    if (alg != KEYNOTE_ALGORITHM_X509)
    {
	/* Parse the private key */
	s = keynote_get_private_key(key);
	if (s == NULL)
	  return NULL;

	/* Decode private key */
	i = kn_decode_key(&dc, s, KEYNOTE_PRIVATE_KEY);
	if (i == -1)
	{
	    free(s);
	    return NULL;
	}
    }
    else /* X509 private key */
    {
	dc.dec_key = key;
	dc.dec_algorithm = alg;
    }

    as = keynote_parse_assertion(buf, buflen, ASSERT_FLAG_SIGGEN);
    if (as == NULL)
    {
	if (alg != KEYNOTE_ALGORITHM_X509)
	{
	    keynote_free_key(dc.dec_key, dc.dec_algorithm);
	    free(s);
	}
	return NULL;
    }

    sig = keynote_sign_assertion(as, sigalg, dc.dec_key, dc.dec_algorithm,
				 vflag);
    if (alg != KEYNOTE_ALGORITHM_X509)
      keynote_free_key(dc.dec_key, dc.dec_algorithm);
    keynote_free_assertion(as);
    if (s != NULL)
      free(s);
    return sig;
}
Пример #4
0
/*
 * Parse an assertion. Set keynote_errno to ERROR_SYNTAX if parsing
 * failed due to certificate badness, and ERROR_MEMORY if memory
 * problem. If more than one assertions have been passed in the
 * buffer, they will be linked.
 */
struct assertion *
keynote_parse_assertion(char *buf, int len, int assertion_flags)
{
    int k, i, j, seen_field = 0, ver = 0, end_of_assertion = 0;
    char *ks, *ke, *ts, *te = (char *) NULL;
    struct assertion *as;

    /* Allocate memory for assertion */
    as = (struct assertion *) calloc(1, sizeof(struct assertion));
    if (as == (struct assertion *) NULL)
    {
        keynote_errno = ERROR_MEMORY;
        return (struct assertion *) NULL;
    }

    /* Keep a copy of the assertion around */
    as->as_buf = strdup(buf);
    if (as->as_buf == (char *) NULL)
    {
        keynote_errno = ERROR_MEMORY;
        keynote_free_assertion(as);
        return (struct assertion *) NULL;
    }

    as->as_flags = assertion_flags & ~(ASSERT_FLAG_SIGGEN |
                                       ASSERT_FLAG_SIGVER);

    /* Skip any leading whitespace */
    for (i = 0, j = len; i < j && isspace((int) as->as_buf[i]); i++)
        ;

    /* Keyword must start at begining of buffer or line */
    if ((i >= j) || ((i != 0) && (as->as_buf[i - 1] != '\n')))
    {
        keynote_free_assertion(as);
        keynote_errno = ERROR_SYNTAX;
        return (struct assertion *) NULL;
    }

    while (i < j)			/* Decomposition loop */
    {
        ks = as->as_buf + i;

        /* Mark begining of assertion for signature purposes */
        if (as->as_startofsignature == (char *) NULL)
            as->as_startofsignature = ks;

        /* This catches comments at the begining of an assertion only */
        if (as->as_buf[i] == '#')	/* Comment */
        {
            seen_field = 1;

            /* Skip until the end of line */
            while ((i< j) && as->as_buf[++i] != '\n')
                ;

            i++;
            continue;  /* Loop */
        }

        /* Advance until we find a keyword separator */
        for (; (as->as_buf[i] != ':') && (i < j); i++)
            ;

        if (i + 1 > j)
        {
            keynote_free_assertion(as);
            keynote_errno = ERROR_SYNTAX;
            return (struct assertion *) NULL;
        }

        /* ks points at begining of keyword, ke points at end */
        ke = as->as_buf + i;

        /* ts points at begining of value field */
        ts = as->as_buf + i + 1;	/* Skip ':' */

        /*
         * Find the end of the field -- means end of buffer,
         * a newline followed by a non-whitespace character,
         * or two newlines.
         */
        while (++i <= j)
        {
            /* If end of buffer, we're at the end of the field */
            if (i == j)
            {
                end_of_assertion = 1;
                te = as->as_buf + i;
                break;
            }

            /* If two newlines, end of assertion */
            if ((as->as_buf[i] == '\n') && (i + 1 < j) &&
                    (as->as_buf[i + 1] == '\n'))
            {
                end_of_assertion = 1;
                te = as->as_buf + i;
                break;
            }

            /* If newline followed by non-whitespace or comment character */
            if ((as->as_buf[i] == '\n') &&
                    (!isspace((int) as->as_buf[i + 1])) &&
                    (as->as_buf[i + 1] != '#'))
            {
                te = as->as_buf + i;
                break;
            }
        }

        i++;

        /*
         * On each of the cases (except the first), we check that:
         *  - we've already seen a keynote-version field (and that
         *    it's the first one that appears in the assertion)
         *  - the signature field, if present, is the last one
         *  - no field appears more than once
         */
        switch (whichkeyword(ks, ke))
        {
        case -1:
            keynote_free_assertion(as);
            return (struct assertion *) NULL;

        case KEYWORD_VERSION:
            if ((ver == 1) || (seen_field == 1))
            {
                keynote_free_assertion(as);
                keynote_errno = ERROR_SYNTAX;
                return (struct assertion *) NULL;
            }

            /* Test for version correctness */
            keynote_get_envlist(ts, te, 1);
            if (keynote_errno != 0)
            {
                keynote_free_assertion(as);
                return (struct assertion *) NULL;
            }

            ver = 1;
            break;

        case KEYWORD_LOCALINIT:
            if (as->as_env != (struct environment *) NULL)
            {
                keynote_free_assertion(as);
                keynote_errno = ERROR_SYNTAX;
                return (struct assertion *) NULL;
            }

            as->as_env = keynote_get_envlist(ts, te, 0);
            if (keynote_errno != 0)
            {
                keynote_free_assertion(as);
                return (struct assertion *) NULL;
            }
            break;

        case KEYWORD_AUTHORIZER:
            if (as->as_authorizer_string_s != (void *) NULL)
            {
                keynote_free_assertion(as);
                keynote_errno = ERROR_SYNTAX;
                return (struct assertion *) NULL;
            }

            as->as_authorizer_string_s = ts;
            as->as_authorizer_string_e = te;
            break;

        case KEYWORD_LICENSEES:
            if (as->as_keypred_s != (char *) NULL)
            {
                keynote_free_assertion(as);
                keynote_errno = ERROR_SYNTAX;
                return (struct assertion *) NULL;
            }

            as->as_keypred_s = ts;
            as->as_keypred_e = te;
            break;

        case KEYWORD_CONDITIONS:
            if (as->as_conditions_s != (char *) NULL)
            {
                keynote_free_assertion(as);
                keynote_errno = ERROR_SYNTAX;
                return (struct assertion *) NULL;
            }

            as->as_conditions_s = ts;
            as->as_conditions_e = te;
            break;

        case KEYWORD_SIGNATURE:
            if (as->as_signature_string_s != (char *) NULL)
            {
                keynote_free_assertion(as);
                keynote_errno = ERROR_SYNTAX;
                return (struct assertion *) NULL;
            }

            end_of_assertion = 1;
            as->as_allbutsignature = ks;
            as->as_signature_string_s = ts;
            as->as_signature_string_e = te;
            break;

        case KEYWORD_COMMENT:
            if (as->as_comment_s != (char *) NULL)
            {
                keynote_free_assertion(as);
                keynote_errno = ERROR_SYNTAX;
                return (struct assertion *) NULL;
            }

            as->as_comment_s = ts;
            as->as_comment_e = te;
            break;
        }

        seen_field = 1;
        if (end_of_assertion == 1)
        {
            /* End of buffer, good termination */
            if ((te == as->as_buf + len) || (te + 1 == as->as_buf + len) ||
                    (*(te) == '\0') || (*(te + 1) == '\0'))
                break;

            /* Check whether there's something else following */
            for (k = 1; te + k < as->as_buf + len && *(te + k) != '\n'; k++)
                if (!isspace((int) *(te + k)))
                {
                    keynote_free_assertion(as);
                    keynote_errno = ERROR_SYNTAX;
                    return (struct assertion *) NULL;
                }

            break; /* Assertion is "properly" terminated */
        }
    }

    /* Check that the basic fields are there */
    if (as->as_authorizer_string_s == (char *) NULL)
    {
        keynote_free_assertion(as);
        keynote_errno = ERROR_SYNTAX;
        return (struct assertion *) NULL;
    }

    /* Signature generation/verification handling */
    if (assertion_flags & ASSERT_FLAG_SIGGEN)
    {
        if (keynote_fix_fields(as, 0) != RESULT_TRUE)
        {
            keynote_free_assertion(as);
            return (struct assertion *) NULL;
        }
    }
    else if (assertion_flags & ASSERT_FLAG_SIGVER)
        if (keynote_fix_fields(as, 1) != RESULT_TRUE)
        {
            keynote_free_assertion(as);
            return (struct assertion *) NULL;
        }

    return as;
}