Beispiel #1
0
/* Load session data from a buffer.
 */
int
_gnutls_session_unpack (gnutls_session_t session,
                        const gnutls_datum_t * packed_session)
{
  int ret;
  gnutls_buffer_st sb;
  opaque id;

  _gnutls_buffer_init (&sb);

  if (packed_session == NULL || packed_session->size == 0)
    {
      gnutls_assert ();
      return GNUTLS_E_INTERNAL_ERROR;
    }

  ret =
    _gnutls_buffer_append_data (&sb, packed_session->data,
                                packed_session->size);
  if (ret < 0)
    {
      gnutls_assert ();
      return ret;
    }

  if (_gnutls_get_auth_info (session) != NULL)
    {
      _gnutls_free_auth_info (session);
    }

  BUFFER_POP (&sb, &id, 1);

  switch (id)
    {
#ifdef ENABLE_SRP
    case GNUTLS_CRD_SRP:
      ret = unpack_srp_auth_info (session, &sb);
      if (ret < 0)
        {
          gnutls_assert ();
          goto error;
        }
      break;
#endif
#ifdef ENABLE_PSK
    case GNUTLS_CRD_PSK:
      ret = unpack_psk_auth_info (session, &sb);
      if (ret < 0)
        {
          gnutls_assert ();
          goto error;
        }
      break;
#endif
#ifdef ENABLE_ANON
    case GNUTLS_CRD_ANON:
      ret = unpack_anon_auth_info (session, &sb);
      if (ret < 0)
        {
          gnutls_assert ();
          return ret;
        }
      break;
#endif
    case GNUTLS_CRD_CERTIFICATE:
      ret = unpack_certificate_auth_info (session, &sb);
      if (ret < 0)
        {
          gnutls_assert ();
          goto error;
        }
      break;
    default:
      gnutls_assert ();
      ret = GNUTLS_E_INTERNAL_ERROR;
      goto error;

    }

  /* Auth_info structures copied. Now copy security_parameters_st. 
   * packed_session must have allocated space for the security parameters.
   */
  ret = unpack_security_parameters (session, &sb);
  if (ret < 0)
    {
      gnutls_assert ();
      goto error;
    }

  ret = _gnutls_ext_unpack (session, &sb);
  if (ret < 0)
    {
      gnutls_assert ();
      goto error;
    }

  ret = 0;

error:
  _gnutls_buffer_clear (&sb);

  return ret;
}
Beispiel #2
0
/**
 * gnutls_certificate_verification_status_print:
 * @status: The status flags to be printed
 * @type: The certificate type
 * @out: Newly allocated datum with (0) terminated string.
 * @flags: should be zero
 *
 * This function will pretty print the status of a verification
 * process -- eg. the one obtained by gnutls_certificate_verify_peers3().
 *
 * The output @out needs to be deallocated using gnutls_free().
 *
 * Returns: On success, %GNUTLS_E_SUCCESS (0) is returned, otherwise a
 *   negative error value.
 *
 * Since: 3.1.4
 **/
int
gnutls_certificate_verification_status_print (unsigned int status,
                       gnutls_certificate_type_t type,
                       gnutls_datum_t * out, unsigned int flags)
{
  gnutls_buffer_st str;
  int ret;

  _gnutls_buffer_init (&str);

  if (status == 0)
    _gnutls_buffer_append_str (&str, _("The certificate is trusted. "));
  else
    _gnutls_buffer_append_str (&str, _("The certificate is NOT trusted. "));

  if (type == GNUTLS_CRT_X509)
    {
      if (status & GNUTLS_CERT_REVOKED)
        _gnutls_buffer_append_str (&str, _("The certificate chain revoked. "));

      if (status & GNUTLS_CERT_REVOCATION_DATA_SUPERSEDED)
         _gnutls_buffer_append_str (&str, _("The revocation data are old and have been superseded. "));

      if (status & GNUTLS_CERT_REVOCATION_DATA_ISSUED_IN_FUTURE)
         _gnutls_buffer_append_str (&str, _("The revocation data are issued with a future date. "));

      if (status & GNUTLS_CERT_SIGNER_NOT_FOUND)
         _gnutls_buffer_append_str (&str, _("The certificate issuer is unknown. "));

      if (status & GNUTLS_CERT_SIGNER_NOT_CA)
         _gnutls_buffer_append_str (&str, _("The certificate issuer is not a CA. "));
      }
    else if (type == GNUTLS_CRT_OPENPGP)
      {
        _gnutls_buffer_append_str (&str, _("The certificate is not trusted. "));

        if (status & GNUTLS_CERT_SIGNER_NOT_FOUND)
          _gnutls_buffer_append_str (&str, _("Could not find a signer of the certificate. "));

        if (status & GNUTLS_CERT_REVOKED)
          _gnutls_buffer_append_str (&str, _("The certificate is revoked. "));
      }

  if (status & GNUTLS_CERT_INSECURE_ALGORITHM)
    _gnutls_buffer_append_str (&str, _("The certificate chain uses insecure algorithm. "));

  if (status & GNUTLS_CERT_SIGNER_CONSTRAINTS_FAILURE)
    _gnutls_buffer_append_str (&str, _("The certificate chain violates the signer's constraints. "));

  if (status & GNUTLS_CERT_NOT_ACTIVATED)
    _gnutls_buffer_append_str (&str, _("The certificate chain uses not yet valid certificate. "));

  if (status & GNUTLS_CERT_EXPIRED)
    _gnutls_buffer_append_str (&str, _("The certificate chain uses expired certificate. "));

  if (status & GNUTLS_CERT_SIGNATURE_FAILURE)
    _gnutls_buffer_append_str (&str, _("The signature in the certificate is invalid. "));

  if (status & GNUTLS_CERT_UNEXPECTED_OWNER)
    _gnutls_buffer_append_str (&str, _("The name in the certificate does not match the expected. "));

  ret = _gnutls_buffer_to_datum( &str, out);
  if (out->size > 0) out->size--;
      
  return ret;
}
Beispiel #3
0
static int encode_tpmkey_url(char **url, const TSS_UUID * uuid,
			     TSS_FLAG storage)
{
	size_t size = (UUID_SIZE * 2 + 4) * 2 + 32;
	uint8_t u1[UUID_SIZE];
	gnutls_buffer_st buf;
	gnutls_datum_t dret;
	int ret;

	*url = gnutls_malloc(size);
	if (*url == NULL)
		return gnutls_assert_val(GNUTLS_E_MEMORY_ERROR);

	_gnutls_buffer_init(&buf);

	memcpy(u1, &uuid->ulTimeLow, 4);
	memcpy(&u1[4], &uuid->usTimeMid, 2);
	memcpy(&u1[6], &uuid->usTimeHigh, 2);
	u1[8] = uuid->bClockSeqHigh;
	u1[9] = uuid->bClockSeqLow;
	memcpy(&u1[10], uuid->rgbNode, 6);

	ret = _gnutls_buffer_append_str(&buf, "tpmkey:uuid=");
	if (ret < 0) {
		gnutls_assert();
		goto cleanup;
	}

	ret =
	    _gnutls_buffer_append_printf(&buf,
					 "%.2x%.2x%.2x%.2x-%.2x%.2x-%.2x%.2x-%.2x%.2x-%.2x%.2x%.2x%.2x%.2x%.2x",
					 (unsigned int) u1[0],
					 (unsigned int) u1[1],
					 (unsigned int) u1[2],
					 (unsigned int) u1[3],
					 (unsigned int) u1[4],
					 (unsigned int) u1[5],
					 (unsigned int) u1[6],
					 (unsigned int) u1[7],
					 (unsigned int) u1[8],
					 (unsigned int) u1[9],
					 (unsigned int) u1[10],
					 (unsigned int) u1[11],
					 (unsigned int) u1[12],
					 (unsigned int) u1[13],
					 (unsigned int) u1[14],
					 (unsigned int) u1[15]);
	if (ret < 0) {
		gnutls_assert();
		goto cleanup;
	}

	ret =
	    _gnutls_buffer_append_printf(&buf, ";storage=%s",
					 (storage ==
					  TSS_PS_TYPE_USER) ? "user" :
					 "system");
	if (ret < 0) {
		gnutls_assert();
		goto cleanup;
	}

	ret = _gnutls_buffer_to_datum(&buf, &dret);
	if (ret < 0) {
		gnutls_assert();
		goto cleanup;
	}

	*url = (char *) dret.data;

	return 0;
      cleanup:
	_gnutls_buffer_clear(&buf);
	return ret;
}
Beispiel #4
0
/**
 * gnutls_init:
 * @session: is a pointer to a #gnutls_session_t type.
 * @flags: indicate if this session is to be used for server or client.
 *
 * This function initializes the provided session. Every
 * session must be initialized before use, and must be deinitialized
 * after used by calling gnutls_deinit().
 *
 * @flags can be any combination of flags from %gnutls_init_flags_t.
 *
 * Note that since version 3.1.2 this function enables some common
 * TLS extensions such as session tickets and OCSP certificate status
 * request in client side by default. To prevent that use the %GNUTLS_NO_EXTENSIONS
 * flag.
 *
 * Returns: %GNUTLS_E_SUCCESS on success, or an error code.
 **/
int gnutls_init(gnutls_session_t * session, unsigned int flags)
{
	int ret;
	record_parameters_st *epoch;
	
	FAIL_IF_LIB_ERROR;

	*session = gnutls_calloc(1, sizeof(struct gnutls_session_int));
	if (*session == NULL)
		return GNUTLS_E_MEMORY_ERROR;

	ret = _gnutls_epoch_alloc(*session, 0, &epoch);
	if (ret < 0) {
		gnutls_assert();
		return GNUTLS_E_MEMORY_ERROR;
	}

	/* Set all NULL algos on epoch 0 */
	_gnutls_epoch_set_null_algos(*session, epoch);

	(*session)->security_parameters.epoch_next = 1;

	(*session)->security_parameters.entity =
	    (flags & GNUTLS_SERVER ? GNUTLS_SERVER : GNUTLS_CLIENT);

	/* the default certificate type for TLS */
	(*session)->security_parameters.cert_type = DEFAULT_CERT_TYPE;

	/* Initialize buffers */
	_gnutls_buffer_init(&(*session)->internals.handshake_hash_buffer);
	_gnutls_buffer_init(&(*session)->internals.hb_remote_data);
	_gnutls_buffer_init(&(*session)->internals.hb_local_data);
	_gnutls_buffer_init(&(*session)->internals.record_presend_buffer);

	_mbuffer_head_init(&(*session)->internals.record_buffer);
	_mbuffer_head_init(&(*session)->internals.record_send_buffer);
	_mbuffer_head_init(&(*session)->internals.record_recv_buffer);

	_mbuffer_head_init(&(*session)->internals.handshake_send_buffer);
	_gnutls_handshake_recv_buffer_init(*session);

	(*session)->internals.expire_time = DEFAULT_EXPIRE_TIME;	/* one hour default */

	gnutls_handshake_set_max_packet_length((*session),
					       MAX_HANDSHAKE_PACKET_SIZE);

	/* set the socket pointers to -1;
	 */
	(*session)->internals.transport_recv_ptr =
	    (gnutls_transport_ptr_t) - 1;
	(*session)->internals.transport_send_ptr =
	    (gnutls_transport_ptr_t) - 1;

	/* set the default maximum record size for TLS
	 */
	(*session)->security_parameters.max_record_recv_size =
	    DEFAULT_MAX_RECORD_SIZE;
	(*session)->security_parameters.max_record_send_size =
	    DEFAULT_MAX_RECORD_SIZE;

	/* everything else not initialized here is initialized
	 * as NULL or 0. This is why calloc is used.
	 */

	_gnutls_handshake_internal_state_init(*session);

	(*session)->internals.extensions_sent_size = 0;

	/* emulate old gnutls behavior for old applications that do not use the priority_*
	 * functions.
	 */
	(*session)->internals.priorities.sr = SR_PARTIAL;

#ifdef HAVE_WRITEV
#ifdef MSG_NOSIGNAL
	if (flags & GNUTLS_NO_SIGNAL)
		gnutls_transport_set_vec_push_function(*session, system_writev_nosignal);
	else
#endif
		gnutls_transport_set_vec_push_function(*session, system_writev);
#else
	gnutls_transport_set_push_function(*session, system_write);
#endif
	(*session)->internals.pull_timeout_func = gnutls_system_recv_timeout;
	(*session)->internals.pull_func = system_read;
	(*session)->internals.errno_func = system_errno;

	/* heartbeat timeouts */
	(*session)->internals.hb_retrans_timeout_ms = 1000;
	(*session)->internals.hb_total_timeout_ms = 60000;

	if (flags & GNUTLS_DATAGRAM) {
		(*session)->internals.dtls.mtu = DTLS_DEFAULT_MTU;
		(*session)->internals.transport = GNUTLS_DGRAM;

		gnutls_dtls_set_timeouts(*session, DTLS_RETRANS_TIMEOUT, 60000);
	} else {
		(*session)->internals.transport = GNUTLS_STREAM;
	}

	/* Enable useful extensions */
	if ((flags & GNUTLS_CLIENT) && !(flags & GNUTLS_NO_EXTENSIONS)) {
#ifdef ENABLE_SESSION_TICKETS
		if (!(flags & GNUTLS_NO_TICKETS))
			gnutls_session_ticket_enable_client(*session);
#endif
#ifdef ENABLE_OCSP
		gnutls_ocsp_status_request_enable_client(*session, NULL, 0,
							 NULL);
#endif
	}

	(*session)->internals.flags = flags;

	return 0;
}
Beispiel #5
0
int
_gnutls_x509_get_dn(ASN1_TYPE asn1_struct,
		    const char *asn1_rdn_name, gnutls_datum_t * dn)
{
	gnutls_buffer_st out_str;
	int k2, k1, result;
	char tmpbuffer1[ASN1_MAX_NAME_SIZE];
	char tmpbuffer2[ASN1_MAX_NAME_SIZE];
	char tmpbuffer3[ASN1_MAX_NAME_SIZE];
	uint8_t value[MAX_STRING_LEN];
	gnutls_datum_t td = { NULL, 0 }, tvd = {
	NULL, 0};
	const char *ldap_desc;
	char oid[MAX_OID_SIZE];
	int len;

	_gnutls_buffer_init(&out_str);

	k1 = 0;
	do {
		k1++;
		/* create a string like "tbsCertList.issuer.rdnSequence.?1"
		 */
		if (asn1_rdn_name[0] != 0)
			snprintf(tmpbuffer1, sizeof(tmpbuffer1), "%s.?%u",
				 asn1_rdn_name, k1);
		else
			snprintf(tmpbuffer1, sizeof(tmpbuffer1), "?%u",
				 k1);

		len = sizeof(value) - 1;
		result =
		    asn1_read_value(asn1_struct, tmpbuffer1, value, &len);

		if (result == ASN1_ELEMENT_NOT_FOUND) {
			if (k1 == 1) {
				gnutls_assert();
				result = GNUTLS_E_REQUESTED_DATA_NOT_AVAILABLE;
				goto cleanup;
			}
			break;
		}

		if (result != ASN1_VALUE_NOT_FOUND) {
			gnutls_assert();
			result = _gnutls_asn2err(result);
			goto cleanup;
		}

		k2 = 0;

		do {		/* Move to the attibute type and values
				 */
			k2++;

			if (tmpbuffer1[0] != 0)
				snprintf(tmpbuffer2, sizeof(tmpbuffer2),
					 "%s.?%u", tmpbuffer1, k2);
			else
				snprintf(tmpbuffer2, sizeof(tmpbuffer2),
					 "?%u", k2);

			/* Try to read the RelativeDistinguishedName attributes.
			 */

			len = sizeof(value) - 1;
			result =
			    asn1_read_value(asn1_struct, tmpbuffer2, value,
					    &len);

			if (result == ASN1_ELEMENT_NOT_FOUND)
				break;
			if (result != ASN1_VALUE_NOT_FOUND) {
				gnutls_assert();
				result = _gnutls_asn2err(result);
				goto cleanup;
			}

			/* Read the OID 
			 */
			_gnutls_str_cpy(tmpbuffer3, sizeof(tmpbuffer3),
					tmpbuffer2);
			_gnutls_str_cat(tmpbuffer3, sizeof(tmpbuffer3),
					".type");

			len = sizeof(oid) - 1;
			result =
			    asn1_read_value(asn1_struct, tmpbuffer3, oid,
					    &len);

			if (result == ASN1_ELEMENT_NOT_FOUND)
				break;
			else if (result != ASN1_SUCCESS) {
				gnutls_assert();
				result = _gnutls_asn2err(result);
				goto cleanup;
			}

			/* Read the Value 
			 */
			_gnutls_str_cpy(tmpbuffer3, sizeof(tmpbuffer3),
					tmpbuffer2);
			_gnutls_str_cat(tmpbuffer3, sizeof(tmpbuffer3),
					".value");

			len = 0;

			result =
			    _gnutls_x509_read_value(asn1_struct,
						    tmpbuffer3, &tvd);
			if (result < 0) {
				gnutls_assert();
				goto cleanup;
			}
#define STR_APPEND(y) if ((result=_gnutls_buffer_append_str( &out_str, y)) < 0) { \
	gnutls_assert(); \
	goto cleanup; \
}
#define DATA_APPEND(x,y) if ((result=_gnutls_buffer_append_data( &out_str, x,y)) < 0) { \
	gnutls_assert(); \
	goto cleanup; \
}
			/*   The encodings of adjoining RelativeDistinguishedNames are separated
			 *   by a comma character (',' ASCII 44).
			 */

			/*   Where there is a multi-valued RDN, the outputs from adjoining
			 *   AttributeTypeAndValues are separated by a plus ('+' ASCII 43)
			 *   character.
			 */
			if (k1 != 1) {	/* the first time do not append a comma */
				if (k2 != 1) {	/* adjoining multi-value RDN */
					STR_APPEND("+");
				} else {
					STR_APPEND(",");
				}
			}

			ldap_desc =
			    gnutls_x509_dn_oid_name(oid,
						    GNUTLS_X509_DN_OID_RETURN_OID);

			STR_APPEND(ldap_desc);
			STR_APPEND("=");

			result =
			    _gnutls_x509_dn_to_string(oid, tvd.data,
						      tvd.size, &td);
			if (result < 0) {
				gnutls_assert();
				_gnutls_debug_log
				    ("Cannot parse OID: '%s' with value '%s'\n",
				     oid, _gnutls_bin2hex(tvd.data,
							  tvd.size,
							  tmpbuffer3,
							  sizeof
							  (tmpbuffer3),
							  NULL));
				goto cleanup;
			}

			DATA_APPEND(td.data, td.size);
			_gnutls_free_datum(&td);
			_gnutls_free_datum(&tvd);
		}
		while (1);
	}
	while (1);

	result = _gnutls_buffer_to_datum(&out_str, dn, 1);
	if (result < 0)
		gnutls_assert();

	goto cleanup1;

      cleanup:
	_gnutls_buffer_clear(&out_str);
      cleanup1:
	_gnutls_free_datum(&td);
	_gnutls_free_datum(&tvd);
	return result;

}
Beispiel #6
0
/**
 * gnutls_init:
 * @session: is a pointer to a #gnutls_session_t structure.
 * @flags: indicate if this session is to be used for server or client.
 *
 * This function initializes the current session to null. Every
 * session must be initialized before use, so internal structures can
 * be allocated.  This function allocates structures which can only
 * be free'd by calling gnutls_deinit().  Returns zero on success.
 *
 * @flags can be one of %GNUTLS_CLIENT and %GNUTLS_SERVER. For a DTLS
 * entity, the flags %GNUTLS_DATAGRAM and  %GNUTLS_NONBLOCK are
 * also available. The latter flag will enable a non-blocking
 * operation of the DTLS timers.
 *
 * Returns: %GNUTLS_E_SUCCESS on success, or an error code.
 **/
int
gnutls_init (gnutls_session_t * session, unsigned int flags)
{
  int ret;
  record_parameters_st *epoch;

  *session = gnutls_calloc (1, sizeof (struct gnutls_session_int));
  if (*session == NULL)
    return GNUTLS_E_MEMORY_ERROR;

  ret = _gnutls_epoch_alloc (*session, 0, &epoch);
  if (ret < 0)
    {
      gnutls_assert ();
      return GNUTLS_E_MEMORY_ERROR;
    }

  /* Set all NULL algos on epoch 0 */
  _gnutls_epoch_set_null_algos (*session, epoch);

  (*session)->security_parameters.epoch_next = 1;

  (*session)->security_parameters.entity = (flags&GNUTLS_SERVER?GNUTLS_SERVER:GNUTLS_CLIENT);

  /* the default certificate type for TLS */
  (*session)->security_parameters.cert_type = DEFAULT_CERT_TYPE;

  /* Initialize buffers */
  _gnutls_buffer_init (&(*session)->internals.handshake_hash_buffer);

  _mbuffer_head_init (&(*session)->internals.record_buffer);
  _mbuffer_head_init (&(*session)->internals.record_send_buffer);
  _mbuffer_head_init (&(*session)->internals.record_recv_buffer);

  _mbuffer_head_init (&(*session)->internals.handshake_send_buffer);
  _gnutls_handshake_recv_buffer_init(*session);

  (*session)->key = gnutls_calloc (1, sizeof (struct gnutls_key_st));
  if ((*session)->key == NULL)
    {
      gnutls_free (*session);
      *session = NULL;
      return GNUTLS_E_MEMORY_ERROR;
    }

  (*session)->internals.expire_time = DEFAULT_EXPIRE_TIME;      /* one hour default */

  gnutls_dh_set_prime_bits ((*session), MIN_DH_BITS);

  gnutls_handshake_set_max_packet_length ((*session),
                                          MAX_HANDSHAKE_PACKET_SIZE);

  /* set the socket pointers to -1;
   */
  (*session)->internals.transport_recv_ptr = (gnutls_transport_ptr_t) - 1;
  (*session)->internals.transport_send_ptr = (gnutls_transport_ptr_t) - 1;

  /* set the default maximum record size for TLS
   */
  (*session)->security_parameters.max_record_recv_size =
    DEFAULT_MAX_RECORD_SIZE;
  (*session)->security_parameters.max_record_send_size =
    DEFAULT_MAX_RECORD_SIZE;

  /* everything else not initialized here is initialized
   * as NULL or 0. This is why calloc is used.
   */

  _gnutls_handshake_internal_state_init (*session);

  /* emulate old gnutls behavior for old applications that do not use the priority_*
   * functions.
   */
  (*session)->internals.priorities.sr = SR_PARTIAL;

#ifdef HAVE_WRITEV
  gnutls_transport_set_vec_push_function (*session, system_writev);
#else
  gnutls_transport_set_push_function (*session, system_write);
#endif
  gnutls_transport_set_pull_function (*session, system_read);
  gnutls_transport_set_errno_function (*session, system_errno);
  gnutls_transport_set_pull_timeout_function (*session, system_recv_timeout);

  if (flags & GNUTLS_DATAGRAM)
    {
      (*session)->internals.dtls.mtu = DTLS_DEFAULT_MTU;
      (*session)->internals.transport = GNUTLS_DGRAM;

      (*session)->internals.dtls.retrans_timeout = 1000;
      (*session)->internals.dtls.total_timeout = 60000;

      (*session)->internals.dtls.record_sw_size = 0;
    }
  else
    (*session)->internals.transport = GNUTLS_STREAM;
  
  if (flags & GNUTLS_NONBLOCK)
    (*session)->internals.dtls.blocking = 0;
  else
    (*session)->internals.dtls.blocking = 1;

  return 0;
}
Beispiel #7
0
/**
 * gnutls_pkcs7_crt_print:
 * @pkcs7: The PKCS7 struct to be printed
 * @format: Indicate the format to use
 * @out: Newly allocated datum with null terminated string.
 *
 * This function will pretty print a signed PKCS #7 structure, suitable for
 * display to a human.
 *
 * Currently the supported formats are %GNUTLS_CRT_PRINT_FULL and
 * %GNUTLS_CRT_PRINT_COMPACT.
 *
 * The output @out needs to be deallocated using gnutls_free().
 *
 * Returns: On success, %GNUTLS_E_SUCCESS (0) is returned, otherwise a
 *   negative error value.
 **/
int gnutls_pkcs7_print(gnutls_pkcs7_t pkcs7,
		       gnutls_certificate_print_formats_t format,
		       gnutls_datum_t * out)
{
	int count, ret, i;
	gnutls_pkcs7_signature_info_st info;
	gnutls_buffer_st str;
	const char *oid;

	_gnutls_buffer_init(&str);

	/* For backwards compatibility with structures using the default OID,
	 * we don't print the eContent Type explicitly */
	oid = gnutls_pkcs7_get_embedded_data_oid(pkcs7);
	if (oid) {
		if (strcmp(oid, DATA_OID) != 0
		    && strcmp(oid, DIGESTED_DATA_OID) != 0) {
			addf(&str, "eContent Type: %s\n", oid);
		}
	}

	for (i = 0;; i++) {
		if (i == 0)
			addf(&str, "Signers:\n");

		ret = gnutls_pkcs7_get_signature_info(pkcs7, i, &info);
		if (ret < 0)
			break;

		print_pkcs7_info(&info, &str, format);
		gnutls_pkcs7_signature_info_deinit(&info);
	}

	if (format == GNUTLS_CRT_PRINT_FULL) {
		gnutls_datum_t data, b64;

		count = gnutls_pkcs7_get_crt_count(pkcs7);

		if (count > 0) {
			addf(&str, "Number of certificates: %u\n\n",
			     count);

			for (i = 0; i < count; i++) {
				ret =
				    gnutls_pkcs7_get_crt_raw2(pkcs7, i, &data);
				if (ret < 0) {
					addf(&str,
					     "Error: cannot print certificate %d\n",
					     i);
					continue;
				}

				ret =
				    gnutls_pem_base64_encode_alloc
				    ("CERTIFICATE", &data, &b64);
				if (ret < 0) {
					gnutls_free(data.data);
					continue;
				}

				adds(&str, (char*)b64.data);
				adds(&str, "\n");
				gnutls_free(b64.data);
				gnutls_free(data.data);
			}
		}

		count = gnutls_pkcs7_get_crl_count(pkcs7);
		if (count > 0) {
			addf(&str, "Number of CRLs: %u\n\n", count);

			for (i = 0; i < count; i++) {
				ret =
				    gnutls_pkcs7_get_crl_raw2(pkcs7, i, &data);
				if (ret < 0) {
					addf(&str,
					     "Error: cannot print certificate %d\n",
					     i);
					continue;
				}

				ret =
				    gnutls_pem_base64_encode_alloc("X509 CRL",
								   &data, &b64);
				if (ret < 0) {
					gnutls_free(data.data);
					continue;
				}

				adds(&str, (char*)b64.data);
				adds(&str, "\n");
				gnutls_free(b64.data);
				gnutls_free(data.data);
			}
		}
	}

	return _gnutls_buffer_to_datum(&str, out, 1);
}
Beispiel #8
0
static
int get_win_urls(const CERT_CONTEXT * cert, char **cert_url, char **key_url,
		 char **label, gnutls_datum_t * der)
{
	BOOL r;
	int ret;
	DWORD tl_size;
	gnutls_datum_t tmp_label = { NULL, 0 };
	char name[MAX_CN * 2];
	char hex[MAX_WID_SIZE * 2 + 1];
	gnutls_buffer_st str;
#ifdef WORDS_BIGENDIAN
	const unsigned bigendian = 1;
#else
	const unsigned bigendian = 0;
#endif

	if (cert == NULL)
		return gnutls_assert_val(GNUTLS_E_REQUESTED_DATA_NOT_AVAILABLE);

	if (der) {
		der->data = gnutls_malloc(cert->cbCertEncoded);
		if (der->data == NULL)
			return gnutls_assert_val(GNUTLS_E_MEMORY_ERROR);

		memcpy(der->data, cert->pbCertEncoded, cert->cbCertEncoded);
		der->size = cert->cbCertEncoded;
	}

	_gnutls_buffer_init(&str);
	if (label)
		*label = NULL;
	if (key_url)
		*key_url = NULL;
	if (cert_url)
		*cert_url = NULL;

	tl_size = sizeof(name);
	r = CertGetCertificateContextProperty(cert, CERT_FRIENDLY_NAME_PROP_ID,
					      name, &tl_size);
	if (r != 0) {		/* optional */
		ret =
		    _gnutls_ucs2_to_utf8(name, tl_size, &tmp_label, bigendian);
		if (ret < 0) {
			gnutls_assert();
			goto fail;
		}
		if (label)
			*label = (char *)tmp_label.data;
	}

	tl_size = sizeof(name);
	r = CertGetCertificateContextProperty(cert, CERT_KEY_IDENTIFIER_PROP_ID,
					      name, &tl_size);
	if (r == 0) {
		gnutls_assert();
		ret = GNUTLS_E_REQUESTED_DATA_NOT_AVAILABLE;
		goto fail;
	}

	if (_gnutls_bin2hex(name, tl_size, hex, sizeof(hex), 0) == NULL) {
		ret = gnutls_assert_val(GNUTLS_E_PARSING_ERROR);
		goto fail;
	}

	ret =
	    _gnutls_buffer_append_printf(&str, WIN_URL "id=%s;type=cert", hex);
	if (ret < 0) {
		gnutls_assert();
		goto fail;
	}

	if (tmp_label.data) {
		ret = _gnutls_buffer_append_str(&str, ";name=");
		if (ret < 0) {
			gnutls_assert();
			goto fail;
		}

		ret =
		    _gnutls_buffer_append_escape(&str, tmp_label.data,
						 tmp_label.size, " ");
		if (ret < 0) {
			gnutls_assert();
			goto fail;
		}
	}

	ret = _gnutls_buffer_append_data(&str, "\x00", 1);
	if (ret < 0) {
		gnutls_assert();
		goto fail;
	}

	if (cert_url)
		*cert_url = (char *)str.data;
	_gnutls_buffer_init(&str);

	ret =
	    _gnutls_buffer_append_printf(&str, WIN_URL "id=%s;type=privkey",
					 hex);
	if (ret < 0) {
		gnutls_assert();
		goto fail;
	}

	if (tmp_label.data) {
		ret = _gnutls_buffer_append_str(&str, ";name=");
		if (ret < 0) {
			gnutls_assert();
			goto fail;
		}

		ret =
		    _gnutls_buffer_append_escape(&str, tmp_label.data,
						 tmp_label.size, " ");
		if (ret < 0) {
			gnutls_assert();
			goto fail;
		}
	}

	ret = _gnutls_buffer_append_data(&str, "\x00", 1);
	if (ret < 0) {
		gnutls_assert();
		goto fail;
	}

	if (key_url)
		*key_url = (char *)str.data;
	_gnutls_buffer_init(&str);

	ret = 0;
	goto cleanup;

 fail:
	if (der)
		gnutls_free(der->data);
	if (cert_url)
		gnutls_free(*cert_url);
	if (key_url)
		gnutls_free(*key_url);
	if (label)
		gnutls_free(*label);
 cleanup:
	_gnutls_buffer_clear(&str);
	return ret;
}