Exemplo n.º 1
0
static int
cert_callback(gnutls_session_t session,
	      const gnutls_datum_t * req_ca_rdn, int nreqs,
	      const gnutls_pk_algorithm_t * sign_algos,
	      int sign_algos_length, gnutls_pcert_st ** pcert,
	      unsigned int *pcert_length, gnutls_privkey_t * pkey)
{
	int result;
	gnutls_x509_dn_t dn;

	if (nreqs != 1) {
		fail("client: invoked to provide client cert, but %d CAs are requested by server.\n",
		 	nreqs);
		return -1;
	}

	if (debug)
		success("client: invoked to provide client cert.\n");

	result = gnutls_x509_dn_init(&dn);
	if (result < 0) {
		fail("client: could not initialize DN.\n");
		return -1;
	}

	result = gnutls_x509_dn_import(dn, req_ca_rdn);
	if (result == 0) {
		gnutls_x509_ava_st val;

		if (debug)
			success("client: imported DN.\n");

		if (gnutls_x509_dn_get_rdn_ava(dn, 0, 0, &val) == 0) {
			if (debug)
				success("client: got RDN 0.\n");

			if (val.value.size == strlen(EXPECT_RDN0)
			    && strncmp((char *) val.value.data,
				       EXPECT_RDN0, val.value.size) == 0) {
				if (debug)
					success
					    ("client: RND 0 correct.\n");
			} else {
				fail("client: RND 0 bad: %.*s\n",
				     val.value.size, val.value.data);
				return -1;
			}
		} else {
			fail("client: could not retrieve RDN 0.\n");
			return -1;
		}

		gnutls_x509_dn_deinit(dn);
	} else {
		fail("client: failed to parse RDN: %s\n",
		     gnutls_strerror(result));
	}

	return 0;
}
Exemplo n.º 2
0
static void print_dn(gnutls_buffer_st * str, const char *prefix,
		     const gnutls_datum_t * raw)
{
	gnutls_x509_dn_t dn = NULL;
	gnutls_datum_t output = { NULL, 0 };
	int ret;

	ret = gnutls_x509_dn_init(&dn);
	if (ret < 0) {
		addf(str, "%s: [error]\n", prefix);
		return;
	}

	ret = gnutls_x509_dn_import(dn, raw);
	if (ret < 0) {
		addf(str, "%s: [error]\n", prefix);
		goto cleanup;
	}

	ret = gnutls_x509_dn_get_str2(dn, &output, 0);
	if (ret < 0) {
		addf(str, "%s: [error]\n", prefix);
		goto cleanup;
	}

	addf(str, "%s: %s\n", prefix, output.data);

 cleanup:
	gnutls_x509_dn_deinit(dn);
	gnutls_free(output.data);
}
Exemplo n.º 3
0
static int
cert_callback (gnutls_session session,
	       const gnutls_datum * req_ca_rdn, int nreqs,
	       const gnutls_pk_algorithm * sign_algos,
	       int sign_algos_length, gnutls_retr_st * st)
{
  int result;
  gnutls_x509_dn_t dn;

  if (nreqs != 1)
    {
      fail ("client: invoked to provide client cert, %d CA .\n", nreqs);
      return -1;
    }

  success ("client: invoked to provide client cert.\n");

  result = gnutls_x509_dn_init (&dn);
  if (result < 0)
    {
      fail ("client: could not initialize DN.\n");
      return -1;
    }

  result = gnutls_x509_dn_import (dn, req_ca_rdn);
  if (result == 0)
    {
      gnutls_x509_ava_st val;

      success ("client: imported DN.\n");

      if (gnutls_x509_dn_get_rdn_ava (dn, 0, 0, &val) == 0)
	{
	  success ("client: got RDN 0.\n");

	  if (val.value.size == strlen (EXPECT_RDN0)
	      && strncmp (val.value.data, EXPECT_RDN0, val.value.size) == 0)
	    {
	      success ("client: RND 0 correct.\n");
	    }
	  else
	    {
	      fail ("client: RND 0 bad: %.*s\n",
		    val.value.size, val.value.data);
	      return -1;
	    }
	}
      else
	{
	  fail ("client: could not retrieve RDN 0.\n");
	  return -1;
	}

      gnutls_x509_dn_deinit (dn);
    }
  else
    {
      fail ("client: failed to parse RDN: %s\n", gnutls_strerror (result));
    }

  return 0;
}
Exemplo n.º 4
0
/* Callback invoked when the SSL server requests a client certificate.  */
static int provide_client_cert(gnutls_session session,
                               const gnutls_datum *req_ca_rdn, int nreqs,
                               const gnutls_pk_algorithm *sign_algos,
                               int sign_algos_length, gnutls_retr_st *st)
{
    ne_session *sess = gnutls_session_get_ptr(session);
    
    if (!sess) {
        return GNUTLS_E_RECEIVED_ILLEGAL_PARAMETER;
    }

    NE_DEBUG(NE_DBG_SSL, "ssl: Client cert provider callback; %d CA names.\n",
             nreqs);

    if (!sess->client_cert && sess->ssl_provide_fn) {
#ifdef HAVE_NEW_DN_API
        const ne_ssl_dname **dns;
        ne_ssl_dname *dnarray;
        unsigned dncount = 0;
        int n;

        dns = ne_malloc(nreqs * sizeof(ne_ssl_dname *));
        dnarray = ne_calloc(nreqs * sizeof(ne_ssl_dname));

        for (n = 0; n < nreqs; n++) {
            gnutls_x509_dn_t dn;

            if (gnutls_x509_dn_init(&dn) == 0) {
                dnarray[n].dn = dn;
                if (gnutls_x509_dn_import(dn, &req_ca_rdn[n]) == 0) {
                    dns[dncount++] = &dnarray[n];
                }
                else {
                    gnutls_x509_dn_deinit(dn);
                }            
            }
        }
       
        NE_DEBUG(NE_DBG_SSL, "ssl: Mapped %d CA names to %u DN objects.\n",
                 nreqs, dncount);

        sess->ssl_provide_fn(sess->ssl_provide_ud, sess, dns, dncount);
        
        for (n = 0; n < nreqs; n++) {
            if (dnarray[n].dn) {
                gnutls_x509_dn_deinit(dnarray[n].dn);
            }
        }

        ne_free(dns);
        ne_free(dnarray);
#else /* HAVE_NEW_DN_API */
        /* Nothing to do here other than pretend no CA names were
         * given, and hope the caller can cope. */
        sess->ssl_provide_fn(sess->ssl_provide_ud, sess, NULL, 0);
#endif
    }

    if (sess->client_cert) {
        gnutls_certificate_type type = gnutls_certificate_type_get(session);
        if (type == GNUTLS_CRT_X509) {
            NE_DEBUG(NE_DBG_SSL, "Supplying client certificate.\n");

            st->type = type;
            st->ncerts = 1;
            st->cert.x509 = &sess->client_cert->cert.subject;
            st->key.x509 = sess->client_cert->pkey;
            
            /* tell GNU TLS not to deallocate the certs. */
            st->deinit_all = 0;
        } else {
            return GNUTLS_E_UNSUPPORTED_CERTIFICATE_TYPE;
        }
    } 
    else {
        NE_DEBUG(NE_DBG_SSL, "No client certificate supplied.\n");
        st->ncerts = 0;
        sess->ssl_cc_requested = 1;
        return 0;
    }

    return 0;
}