Ejemplo n.º 1
0
Archivo: tgs.c Proyecto: Jactry/shishi
/**
 * shishi_tgs_rep_der:
 * @tgs: structure that holds information about TGS exchange
 * @out: output array with newly allocated DER encoding of TGS-REP.
 * @outlen: length of output array with DER encoding of TGS-REP.
 *
 * DER encode TGS-REP. @out is allocated by this function, and it is
 * the responsibility of caller to deallocate it.
 *
 * Return value: Returns SHISHI_OK iff successful.
 **/
int
shishi_tgs_rep_der (Shishi_tgs * tgs, char **out, size_t * outlen)
{
  int rc;

  rc = shishi_asn1_to_der (tgs->handle, tgs->tgsrep, out, outlen);
  if (rc != SHISHI_OK)
    return rc;

  return SHISHI_OK;
}
Ejemplo n.º 2
0
/**
 * shishi_kdcreq_add_padata_tgs:
 * @handle: shishi handle as allocated by shishi_init().
 * @kdcreq: KDC-REQ to add PA-DATA to.
 * @apreq: AP-REQ to add as PA-DATA.
 *
 * Add TGS pre-authentication data to KDC-REQ.  The data is an AP-REQ
 * that authenticates the request.  This functions simply DER encodes
 * the AP-REQ and calls shishi_kdcreq_add_padata() with a
 * SHISHI_PA_TGS_REQ padatatype.
 *
 * Return value: Returns SHISHI_OK iff successful.
 **/
int
shishi_kdcreq_add_padata_tgs (Shishi * handle,
                              Shishi_asn1 kdcreq, Shishi_asn1 apreq)
{
    int res;
    char *data;
    size_t datalen;

    res = shishi_asn1_to_der (handle, apreq, &data, &datalen);
    if (res != SHISHI_OK)
    {
        shishi_error_printf (handle, "Could not DER encode AP-REQ: %s\n",
                             shishi_strerror (res));
        return res;
    }

    res = shishi_kdcreq_add_padata (handle, kdcreq,
                                    SHISHI_PA_TGS_REQ, data, datalen);
    free (data);
    if (res != SHISHI_OK)
        return res;

    return res;
}
Ejemplo n.º 3
0
/**
 * shishi_apreq_add_authenticator:
 * @handle: shishi handle as allocated by shishi_init().
 * @apreq: AP-REQ to add authenticator field to.
 * @key: key to to use for encryption.
 * @keyusage: cryptographic key usage value to use in encryption.
 * @authenticator: authenticator as allocated by shishi_authenticator().
 *
 * Encrypts DER encoded authenticator using key and store it in the
 * AP-REQ.
 *
 * Return value: Returns SHISHI_OK iff successful.
 **/
int
shishi_apreq_add_authenticator (Shishi * handle,
				Shishi_asn1 apreq,
				Shishi_key * key,
				int keyusage, Shishi_asn1 authenticator)
{
  int res;
  char *buf;
  size_t buflen;
  char *der;
  size_t derlen;

  res = shishi_asn1_to_der (handle, authenticator, &der, &derlen);
  if (res != SHISHI_OK)
    {
      shishi_error_printf (handle, "Could not DER encode authenticator: %s\n",
			   shishi_strerror (res));
      return res;
    }

  res = shishi_encrypt (handle, key, keyusage, der, derlen, &buf, &buflen);

  free (der);

  if (res != SHISHI_OK)
    {
      shishi_error_printf (handle, "Cannot encrypt authenticator.\n");
      return res;
    }

  res = shishi_apreq_set_authenticator (handle, apreq, shishi_key_type (key),
					shishi_key_version (key),
					buf, buflen);

  return res;
}
Ejemplo n.º 4
0
/**
 * shishi_kdcreq_add_padata_preauth:
 * @handle: shishi handle as allocated by shishi_init().
 * @kdcreq: KDC-REQ to add pre-authentication data to.
 * @key: Key used to encrypt pre-auth data.
 *
 * Add pre-authentication data to KDC-REQ.
 *
 * Return value: Returns SHISHI_OK iff successful.
 **/
int
shishi_kdcreq_add_padata_preauth (Shishi * handle,
                                  Shishi_asn1 kdcreq, Shishi_key * key)
{
    char *der, *data;
    size_t derlen, datalen;
    Shishi_asn1 pa;
    struct timeval tv;
    int rc;
    Shishi_asn1 ed;

    pa = shishi_asn1_pa_enc_ts_enc (handle);
    if (!pa)
        return SHISHI_ASN1_ERROR;

    rc = gettimeofday (&tv, NULL);
    if (rc != 0)
        return SHISHI_GETTIMEOFDAY_ERROR;

    rc = shishi_asn1_write (handle, pa, "patimestamp",
                            shishi_generalize_time (handle, tv.tv_sec),
                            SHISHI_GENERALIZEDTIME_LENGTH);
    if (rc != SHISHI_OK)
        return rc;

    rc = shishi_asn1_write_integer (handle, pa, "pausec", tv.tv_usec);
    if (rc != SHISHI_OK)
        return rc;

    rc = shishi_asn1_to_der (handle, pa, &der, &derlen);
    if (rc != SHISHI_OK)
        return rc;

    rc = shishi_encrypt (handle, key, SHISHI_KEYUSAGE_ASREQ_PA_ENC_TIMESTAMP,
                         der, derlen, &data, &datalen);
    free (der);
    if (rc != SHISHI_OK)
        return rc;

    ed = shishi_asn1_encrypteddata (handle);
    if (!ed)
        return SHISHI_ASN1_ERROR;

    rc = shishi_asn1_write_integer (handle, ed, "etype", shishi_key_type (key));
    if (rc != SHISHI_OK)
        return rc;

    rc = shishi_asn1_write (handle, ed, "cipher", data, datalen);
    if (rc != SHISHI_OK)
        return rc;

    rc = shishi_asn1_write (handle, ed, "kvno", NULL, 0);
    if (rc != SHISHI_OK)
        return rc;

    rc = shishi_asn1_to_der (handle, ed, &der, &derlen);
    free (data);
    if (rc != SHISHI_OK)
        return rc;

    rc = shishi_kdcreq_add_padata (handle, kdcreq, SHISHI_PA_ENC_TIMESTAMP,
                                   der, derlen);
    free (der);
    if (rc != SHISHI_OK)
        return rc;

    return rc;
}
Ejemplo n.º 5
0
/* Allows a remotely initiated security context between the
   application and a remote peer to be established, using krb5.
   Assumes context_handle is valid. */
OM_uint32
gss_krb5_accept_sec_context (OM_uint32 * minor_status,
                             gss_ctx_id_t * context_handle,
                             const gss_cred_id_t acceptor_cred_handle,
                             const gss_buffer_t input_token_buffer,
                             const gss_channel_bindings_t input_chan_bindings,
                             gss_name_t * src_name,
                             gss_OID * mech_type,
                             gss_buffer_t output_token,
                             OM_uint32 * ret_flags,
                             OM_uint32 * time_rec,
                             gss_cred_id_t * delegated_cred_handle)
{
    gss_buffer_desc data;
    char *in;
    size_t inlen;
    gss_ctx_id_t cx;
    _gss_krb5_ctx_t cxk5;
    _gss_krb5_cred_t crk5;
    int rc;

    if (minor_status)
        *minor_status = 0;

    if (ret_flags)
        *ret_flags = 0;

    if (!acceptor_cred_handle)
        /* XXX support GSS_C_NO_CREDENTIAL: acquire_cred() default server */
        return GSS_S_NO_CRED;

    if (*context_handle)
        return GSS_S_FAILURE;

    crk5 = acceptor_cred_handle->krb5;

    cx = calloc (sizeof (*cx), 1);
    if (!cx)
    {
        if (minor_status)
            *minor_status = ENOMEM;
        return GSS_S_FAILURE;
    }

    cxk5 = calloc (sizeof (*cxk5), 1);
    if (!cxk5)
    {
        free (cx);
        if (minor_status)
            *minor_status = ENOMEM;
        return GSS_S_FAILURE;
    }

    cx->mech = GSS_KRB5;
    cx->krb5 = cxk5;
    /* XXX cx->peer?? */
    *context_handle = cx;

    cxk5->sh = crk5->sh;
    cxk5->key = crk5->key;
    cxk5->acceptor = 1;

    rc = shishi_ap (cxk5->sh, &cxk5->ap);
    if (rc != SHISHI_OK)
        return GSS_S_FAILURE;

    rc = gss_decapsulate_token (input_token_buffer, GSS_KRB5, &in, &inlen);
    if (!rc)
        return GSS_S_BAD_MIC;

    if (inlen < TOK_LEN)
        return GSS_S_BAD_MIC;

    if (memcmp (in, TOK_AP_REQ, TOK_LEN) != 0)
        return GSS_S_BAD_MIC;

    rc = shishi_ap_req_der_set (cxk5->ap, in + TOK_LEN, inlen - TOK_LEN);
    if (rc != SHISHI_OK)
        return GSS_S_FAILURE;

    rc = shishi_ap_req_process (cxk5->ap, crk5->key);
    if (rc != SHISHI_OK)
    {
        if (minor_status)
            *minor_status = GSS_KRB5_S_G_VALIDATE_FAILED;
        return GSS_S_FAILURE;
    }

    rc = shishi_authenticator_seqnumber_get (cxk5->sh,
            shishi_ap_authenticator (cxk5->ap),
            &cxk5->initseqnr);
    if (rc != SHISHI_OK)
        return GSS_S_FAILURE;

    rc = _gss_krb5_checksum_parse (minor_status,
                                   context_handle,
                                   input_chan_bindings);
    if (rc != GSS_S_COMPLETE)
        return GSS_S_FAILURE;

    cxk5->tkt = shishi_ap_tkt (cxk5->ap);
    cxk5->key = shishi_ap_key (cxk5->ap);

    if (shishi_apreq_mutual_required_p (crk5->sh, shishi_ap_req (cxk5->ap)))
    {
        Shishi_asn1 aprep;

        rc = shishi_ap_rep_asn1 (cxk5->ap, &aprep);
        if (rc != SHISHI_OK)
        {
            printf ("Error creating AP-REP: %s\n", shishi_strerror (rc));
            return GSS_S_FAILURE;
        }

        rc = shishi_encapreppart_seqnumber_get (cxk5->sh,
                                                shishi_ap_encapreppart (cxk5->
                                                        ap),
                                                &cxk5->acceptseqnr);
        if (rc != SHISHI_OK)
        {
            /* A strict 1964 implementation would return
               GSS_S_DEFECTIVE_TOKEN here.  gssapi-cfx permit absent
               sequence number, though. */
            cxk5->acceptseqnr = 0;
        }

        {
            char *der;
            size_t len;

            rc = shishi_asn1_to_der (crk5->sh, aprep, &der, &len);
            if (rc != SHISHI_OK)
            {
                printf ("Error der encoding aprep: %s\n", shishi_strerror (rc));
                return GSS_S_FAILURE;
            }
            data.value = der;
            data.length = len;
        }

        rc = gss_encapsulate_token_prefix (&data, TOK_AP_REP, TOK_LEN,
                                           GSS_KRB5, output_token);
        if (!rc)
            return GSS_S_FAILURE;

        if (ret_flags)
            *ret_flags = GSS_C_MUTUAL_FLAG;
    }
    else
    {
        output_token->value = NULL;
        output_token->length = 0;
    }

    if (src_name)
    {
        gss_name_t p;

        p = malloc (sizeof (*p));
        if (!p)
        {
            if (minor_status)
                *minor_status = ENOMEM;
            return GSS_S_FAILURE;
        }

        rc = shishi_encticketpart_client (cxk5->sh,
                                          shishi_tkt_encticketpart (cxk5->tkt),
                                          &p->value, &p->length);
        if (rc != SHISHI_OK)
            return GSS_S_FAILURE;

        p->type = GSS_KRB5_NT_PRINCIPAL_NAME;

        *src_name = p;
    }

    /* PROT_READY is not mentioned in 1964/gssapi-cfx but we support
       it anyway. */
    if (ret_flags)
        *ret_flags |= GSS_C_PROT_READY_FLAG;

    if (minor_status)
        *minor_status = 0;
    return GSS_S_COMPLETE;
}
Ejemplo n.º 6
0
void
test (Shishi * handle)
{
  Shishi_asn1 a;
  char *p, *buf, *buf2;
  int res;
  size_t n, m;
  int32_t t;
  uint32_t s;

  /* shishi_authenticator */
  a = shishi_authenticator (handle);
  if (debug)
    printf ("shishi_authenticator () => `%p'.\n", a);
  if (a)
    success ("shishi_authenticator() OK\n");
  else
    fail ("shishi_authenticator() failed\n");

  if (debug)
    shishi_authenticator_print (handle, stdout, a);

  res = shishi_authenticator_remove_subkey (handle, a);
  if (res == SHISHI_OK)
    success ("shishi_authenticator_remove_subkey() OK\n");
  else
    fail ("shishi_authenticator_remove_subkey() failed\n");

  /* shishi_authenticator_seqnumber_get */
  res = shishi_authenticator_seqnumber_get (handle, a, &s);
  if (res == SHISHI_OK)
    success ("shishi_authenticator_seqnumber_get() OK\n");
  else
    fail ("shishi_authenticator_seqnumber_get() failed\n");

  /* shishi_authenticator_seqnumber_set */
  res = shishi_authenticator_seqnumber_set (handle, a, 42);
  if (res == SHISHI_OK)
    success ("shishi_authenticator_seqnumber_set() OK\n");
  else
    fail ("shishi_authenticator_seqnumber_set() failed\n");

  /* shishi_authenticator_seqnumber_get */
  res = shishi_authenticator_seqnumber_get (handle, a, &s);
  if (res == SHISHI_OK && s == 42)
    success ("shishi_authenticator_seqnumber_get() OK\n");
  else
    fail ("shishi_authenticator_seqnumber_get() failed\n");

  /* shishi_authenticator_seqnumber_remove */
  res = shishi_authenticator_seqnumber_remove (handle, a);
  if (res == SHISHI_OK)
    success ("shishi_authenticator_seqnumber_remove() OK\n");
  else
    fail ("shishi_authenticator_seqnumber_remove() failed\n");

  /* shishi_authenticator_set_crealm */
  res = shishi_authenticator_set_crealm (handle, a, "foo");
  if (res == SHISHI_OK)
    success ("shishi_authenticator_set_crealm() OK\n");
  else
    fail ("shishi_authenticator_set_crealm() failed\n");

  /* shishi_authenticator_client_set */
  res = shishi_authenticator_client_set (handle, a, "foo/bar/baz");
  if (res == SHISHI_OK)
    success ("shishi_authenticator_client_set() OK\n");
  else
    fail ("shishi_authenticator_client_set() failed\n");

  /* shishi_authenticator_client */
  res = shishi_authenticator_client (handle, a, &buf, &n);
  if (debug)
    escapeprint (buf, n);
  if (res == SHISHI_OK &&
      n == strlen ("foo/bar/baz") && memcmp (buf, "foo/bar/baz", n) == 0)
    success ("shishi_authenticator_client() OK\n");
  else
    fail ("shishi_authenticator_client() failed\n");
  if (res == SHISHI_OK)
    free (buf);

  /* shishi_authenticator_client_set */
  res = shishi_authenticator_client_set (handle, a, "foo");
  if (res == SHISHI_OK)
    success ("shishi_authenticator_client_set() OK\n");
  else
    fail ("shishi_authenticator_client_set() failed\n");

  /* shishi_authenticator_client */
  res = shishi_authenticator_client (handle, a, &buf, &n);
  if (debug)
    escapeprint (buf, n);
  if (res == SHISHI_OK && n == strlen ("foo") && memcmp (buf, "foo", n) == 0)
    success ("shishi_authenticator_client() OK\n");
  else
    fail ("shishi_authenticator_client() failed\n");
  if (res == SHISHI_OK)
    free (buf);

  /* shishi_authenticator_set_crealm */
  res = shishi_authenticator_set_crealm (handle, a, "bar");
  if (res == SHISHI_OK)
    success ("shishi_authenticator_set_crealm() OK\n");
  else
    fail ("shishi_authenticator_set_crealm() failed\n");

  /* shishi_authenticator_clientrealm */
  res = shishi_authenticator_clientrealm (handle, a, &buf, &n);
  if (debug)
    escapeprint (buf, n);
  if (res == SHISHI_OK &&
      n == strlen ("foo@bar") && memcmp (buf, "foo@bar", n) == 0)
    success ("shishi_authenticator_clientrealm() OK\n");
  else
    fail ("shishi_authenticator_clientrealm() failed\n");
  if (res == SHISHI_OK)
    free (buf);

  /* shishi_authenticator_add_authorizationdata */
  res = shishi_authenticator_add_authorizationdata (handle, a, 42, "baz", 3);
  if (res == SHISHI_OK)
    success ("shishi_authenticator_add_authorizationdata() OK\n");
  else
    fail ("shishi_authenticator_add_authorizationdata() failed\n");

  /* shishi_authenticator_authorizationdata */
  res = shishi_authenticator_authorizationdata (handle, a, &t, &buf, &m, 1);
  if (debug)
    escapeprint (buf, m);
  if (res == SHISHI_OK && t == 42 && m == 3 && memcmp (buf, "baz", 3) == 0)
    success ("shishi_authenticator_authorizationdata() OK\n");
  else
    fail ("shishi_authenticator_authorizationdata() failed\n");
  if (res == SHISHI_OK)
    free (buf);

  /* shishi_authenticator_authorizationdata */
  res = shishi_authenticator_authorizationdata (handle, a, &t, &buf, &m, 2);
  if (res == SHISHI_OK)
    free (buf);
  if (res == SHISHI_OUT_OF_RANGE)
    success ("shishi_authenticator_authorizationdata() OK\n");
  else
    fail ("shishi_authenticator_authorizationdata() failed\n");

  /* shishi_authenticator_remove_cksum */
  res = shishi_authenticator_remove_cksum (handle, a);
  if (res == SHISHI_OK)
    success ("shishi_authenticator_remove_cksum() OK\n");
  else
    fail ("shishi_authenticator_remove_cksum() failed\n");

  /* shishi_asn1_to_der */
  res = shishi_asn1_to_der (handle, a, &buf, &n);
  if (res == SHISHI_OK)
    success ("shishi_asn1_to_der() OK\n");
  else
    n = 0, fail ("shishi_asn1_to_der() failed\n");

  /* shishi_authenticator_to_file */
  res = shishi_authenticator_to_file (handle, a, SHISHI_FILETYPE_TEXT,
				      "authenticator.tmp");
  if (res == SHISHI_OK)
    success ("shishi_authenticator_to_file() OK\n");
  else
    fail ("shishi_authenticator_to_file() failed\n");

  /* shishi_asn1_done */
  shishi_asn1_done (handle, a);
  success ("shishi_asn1_done() OK\n");

  a = NULL;

  /* shishi_authenticator_from_file */
  res = shishi_authenticator_from_file (handle, &a, SHISHI_FILETYPE_TEXT,
					"authenticator.tmp");
  if (res == SHISHI_OK)
    success ("shishi_authenticator_from_file() OK\n");
  else
    fail ("shishi_authenticator_from_file() failed\n");

  if (debug)
    {
      /* shishi_authenticator_print */
      res = shishi_authenticator_print (handle, stdout, a);
      if (res == SHISHI_OK)
	success ("shishi_authenticator_print() OK\n");
      else
	fail ("shishi_authenticator_print() failed\n");
    }

  /* shishi_asn1_to_der */
  res = shishi_asn1_to_der (handle, a, &buf2, &m);
  if (res == SHISHI_OK)
    success ("shishi_asn1_to_der() OK\n");
  else
    n = 0, fail ("shishi_asn1_to_der() failed\n");

  /* Compare DER encodings of authenticators */
  if (n > 0 && m > 0 && n == m && memcmp (buf, buf2, n) == 0)
    success ("DER comparison OK\n");
  else
    fail ("DER comparison failed\n");

  free (buf);
  free (buf2);

  /* shishi_authenticator_cusec_set */
  res = shishi_authenticator_cusec_set (handle, a, 4711);
  if (res == SHISHI_OK)
    success ("shishi_authenticator_cusec_set() OK\n");
  else
    fail ("shishi_authenticator_cusec_set() failed\n");

  /* shishi_authenticator_cusec_get */
  res = shishi_authenticator_cusec_get (handle, a, &s);
  if (debug)
    printf ("shishi_authenticator_cusec_get () => `%d'.\n", t);
  if (res == SHISHI_OK && s == 4711)
    success ("shishi_authenticator_cusec_get() OK\n");
  else
    fail ("shishi_authenticator_cusec_get() failed\n");

  /* shishi_authenticator_ctime_set */
  res = shishi_authenticator_ctime_set (handle, a, "19700101011831Z");
  if (res == SHISHI_OK)
    success ("shishi_authenticator_ctime_set() OK\n");
  else
    fail ("shishi_authenticator_ctime_set() failed\n");

  /* shishi_authenticator_ctime */
  res = shishi_authenticator_ctime (handle, a, &p);
  if (debug)
    escapeprint (p, strlen (p));
  if (res == SHISHI_OK && memcmp (p, "19700101011831Z", 15) == 0)
    success ("shishi_authenticator_ctime() OK\n");
  else
    fail ("shishi_authenticator_ctime() failed\n");
  if (res == SHISHI_OK)
    free (p);

  /* shishi_asn1_to_der */
  res = shishi_asn1_to_der (handle, a, &buf, &n);
  if (res == SHISHI_OK)
    success ("shishi_asn1_to_der() OK\n");
  else
    n = 0, fail ("shishi_asn1_to_der() failed\n");
  if (debug)
    {
      shishi_authenticator_print (handle, stdout, a);
      hexprint (buf, n);
      puts ("");
      hexprint (authenticator, sizeof (authenticator));
      puts ("");
    }
  if (n == sizeof (authenticator) &&
      n == AUTHENTICATOR_LEN && memcmp (authenticator, buf, n) == 0)
    success ("DER comparison OK\n");
  else
    fail ("DER comparison failed\n");

  free (buf);

  /* shishi_authenticator_clear_authorizationdata */
  res = shishi_authenticator_clear_authorizationdata (handle, a);
  if (res == SHISHI_OK)
    success ("shishi_authenticator_clear_authorizationdata() OK\n");
  else
    fail ("shishi_authenticator_clear_authorizationdata() failed\n");

  /* shishi_asn1_to_der */
  res = shishi_asn1_to_der (handle, a, &buf, &n);
  if (res == SHISHI_OK)
    success ("shishi_asn1_to_der() OK\n");
  else
    n = 0, fail ("shishi_asn1_to_der() failed\n");
  if (debug)
    {
      shishi_authenticator_print (handle, stdout, a);
      hexprint (buf, n);
      puts ("");
      hexprint (authenticator2, sizeof (authenticator2));
      puts ("");
    }
  if (n == sizeof (authenticator2) &&
      n == AUTHENTICATOR2_LEN && memcmp (authenticator2, buf, n) == 0)
    success ("DER comparison OK\n");
  else
    fail ("DER comparison failed\n");

  free (buf);

  /* unlink */
  res = unlink ("authenticator.tmp");
  if (res == 0)
    success ("unlink() OK\n");
  else
    fail ("unlink() failed\n");

  /* shishi_asn1_done */
  shishi_asn1_done (handle, a);
  success ("shishi_asn1_done() OK\n");
}