Beispiel #1
0
/* the same as _gnutls_handshake_sign_cert_vrfy except that it is made for TLS 1.2
 */
static int
_gnutls_handshake_sign_cert_vrfy12 (gnutls_session_t session,
                                    gnutls_pcert_st* cert, gnutls_privkey_t pkey,
                                    gnutls_datum_t * signature)
{
  gnutls_datum_t dconcat;
  int ret;
  opaque concat[MAX_SIG_SIZE];
  digest_hd_st td;
  gnutls_sign_algorithm_t sign_algo;
  gnutls_digest_algorithm_t hash_algo;
  digest_hd_st *handshake_td;

  sign_algo =
    _gnutls_session_get_sign_algo (session, cert);
  if (sign_algo == GNUTLS_SIGN_UNKNOWN)
    {
      gnutls_assert ();
      return GNUTLS_E_UNKNOWN_PK_ALGORITHM;
    }

  hash_algo = _gnutls_sign_get_hash_algorithm (sign_algo);

  _gnutls_debug_log ("sign handshake cert vrfy: picked %s with %s\n",
                    gnutls_sign_algorithm_get_name (sign_algo),
                    gnutls_mac_get_name (hash_algo));

  if ((gnutls_mac_algorithm_t)hash_algo == session->internals.handshake_mac_handle.tls12.sha1.algorithm)
    handshake_td = &session->internals.handshake_mac_handle.tls12.sha1;
  else if ((gnutls_mac_algorithm_t)hash_algo == session->internals.handshake_mac_handle.tls12.sha256.algorithm)
    handshake_td = &session->internals.handshake_mac_handle.tls12.sha256;
  else
    return gnutls_assert_val(GNUTLS_E_INTERNAL_ERROR); /* too bad we only support SHA1 and SHA256 */

  ret = _gnutls_hash_copy (&td, handshake_td);
  if (ret < 0)
    {
      gnutls_assert ();
      return ret;
    }

  _gnutls_hash_deinit (&td, concat);

  dconcat.data = concat;
  dconcat.size = _gnutls_hash_get_algo_len (hash_algo);

  ret = sign_tls_hash (session, hash_algo, cert, pkey, &dconcat, signature);
  if (ret < 0)
    {
      gnutls_assert ();
      return ret;
    }

  return sign_algo;
}
Beispiel #2
0
/* the same as _gnutls_handshake_sign_crt_vrfy except that it is made for TLS 1.2
 */
static int
_gnutls_handshake_sign_crt_vrfy12(gnutls_session_t session,
				  gnutls_pcert_st * cert,
				  gnutls_privkey_t pkey,
				  gnutls_datum_t * signature)
{
	gnutls_datum_t dconcat;
	int ret;
	uint8_t concat[MAX_SIG_SIZE];
	gnutls_sign_algorithm_t sign_algo;
	const mac_entry_st *me;

	sign_algo = _gnutls_session_get_sign_algo(session, cert);
	if (sign_algo == GNUTLS_SIGN_UNKNOWN) {
		gnutls_assert();
		return GNUTLS_E_UNKNOWN_PK_ALGORITHM;
	}

	gnutls_sign_algorithm_set_client(session, sign_algo);

	me = hash_to_entry(gnutls_sign_get_hash_algorithm(sign_algo));

	_gnutls_debug_log("sign handshake cert vrfy: picked %s with %s\n",
			  gnutls_sign_algorithm_get_name(sign_algo),
			  _gnutls_mac_get_name(me));

	ret =
	    _gnutls_hash_fast((gnutls_digest_algorithm_t)me->id,
			      session->internals.handshake_hash_buffer.
			      data,
			      session->internals.handshake_hash_buffer.
			      length, concat);
	if (ret < 0)
		return gnutls_assert_val(ret);

	dconcat.data = concat;
	dconcat.size = _gnutls_hash_get_algo_len(me);

	ret = sign_tls_hash(session, me, cert, pkey, &dconcat, signature);
	if (ret < 0) {
		gnutls_assert();
		return ret;
	}

	return sign_algo;
}
void __certificate_properties_fill_cert_signature(GtkTreeStore *store, GtkTreeIter *parent, gnutls_x509_crt_t *certificate)
{
    int result;
    GtkTreeIter j;
    GtkTreeIter k;
    const gchar *name = NULL;

    result = gnutls_x509_crt_get_signature_algorithm(*certificate);
    name = gnutls_sign_algorithm_get_name(result);

    gtk_tree_store_append(store, &j, parent);
    gtk_tree_store_set(store, &j, CERTIFICATE_PROPERTIES_COL_NAME, _("Signature"), -1);

    gtk_tree_store_append(store, &k, &j);
    gtk_tree_store_set(store, &k, CERTIFICATE_PROPERTIES_COL_NAME, _("Algorithm"), CERTIFICATE_PROPERTIES_COL_VALUE, name, -1);

    gtk_tree_store_append(store, &k, &j);
    gtk_tree_store_set(store, &k, CERTIFICATE_PROPERTIES_COL_NAME, _("Parameters"), CERTIFICATE_PROPERTIES_COL_VALUE, _("(unknown)"), -1);
}
Beispiel #4
0
void
doit (void)
{
    if (debug)
    {
        printf ("GnuTLS header version %s.\n", GNUTLS_VERSION);
        printf ("GnuTLS library version %s.\n", gnutls_check_version (NULL));
    }

    if (!gnutls_check_version (GNUTLS_VERSION))
        fail ("gnutls_check_version ERROR\n");

    {
        const gnutls_pk_algorithm_t *algs;
        size_t i;
        int pk;

        algs = gnutls_pk_list ();
        if (!algs)
            fail ("gnutls_pk_list return NULL\n");

        for (i = 0; algs[i]; i++)
        {
            if (debug)
                printf ("pk_list[%d] = %d = %s = %d\n", (int) i, algs[i],
                        gnutls_pk_algorithm_get_name (algs[i]),
                        gnutls_pk_get_id (gnutls_pk_algorithm_get_name (algs[i])));
            if (gnutls_pk_get_id (gnutls_pk_algorithm_get_name (algs[i]))
                    != algs[i])
                fail ("gnutls_pk id's doesn't match\n");
        }

        pk = gnutls_pk_get_id ("foo");
        if (pk != GNUTLS_PK_UNKNOWN)
            fail ("gnutls_pk unknown test failed (%d)\n", pk);

        if (debug)
            success ("gnutls_pk_list ok\n");
    }

    {
        const gnutls_sign_algorithm_t *algs;
        size_t i;
        int pk;

        algs = gnutls_sign_list ();
        if (!algs)
            fail ("gnutls_sign_list return NULL\n");

        for (i = 0; algs[i]; i++)
        {
            if (debug)
                printf ("sign_list[%d] = %d = %s = %d\n", (int) i, algs[i],
                        gnutls_sign_algorithm_get_name (algs[i]),
                        gnutls_sign_get_id (gnutls_sign_algorithm_get_name
                                            (algs[i])));
            if (gnutls_sign_get_id (gnutls_sign_algorithm_get_name (algs[i])) !=
                    algs[i])
                fail ("gnutls_sign id's doesn't match\n");
        }

        pk = gnutls_sign_get_id ("foo");
        if (pk != GNUTLS_PK_UNKNOWN)
            fail ("gnutls_sign unknown test failed (%d)\n", pk);

        if (debug)
            success ("gnutls_sign_list ok\n");
    }
}
Beispiel #5
0
void
print_list (const char *priorities, int verbose)
{
    size_t i;
    int ret;
    unsigned int idx;
    const char *name;
    const char *err;
    unsigned char id[2];
    gnutls_kx_algorithm_t kx;
    gnutls_cipher_algorithm_t cipher;
    gnutls_mac_algorithm_t mac;
    gnutls_protocol_t version;
    gnutls_priority_t pcache;
    const unsigned int *list;

    if (priorities != NULL)
      {
          printf ("Cipher suites for %s\n", priorities);

          ret = gnutls_priority_init (&pcache, priorities, &err);
          if (ret < 0)
            {
                fprintf (stderr, "Syntax error at: %s\n", err);
                exit (1);
            }

          for (i = 0;; i++)
            {
                ret =
                    gnutls_priority_get_cipher_suite_index (pcache, i,
                                                            &idx);
                if (ret == GNUTLS_E_REQUESTED_DATA_NOT_AVAILABLE)
                    break;
                if (ret == GNUTLS_E_UNKNOWN_CIPHER_SUITE)
                    continue;

                name =
                    gnutls_cipher_suite_info (idx, id, NULL, NULL, NULL,
                                              &version);

                if (name != NULL)
                    printf ("%-50s\t0x%02x, 0x%02x\t%s\n",
                            name, (unsigned char) id[0],
                            (unsigned char) id[1],
                            gnutls_protocol_get_name (version));
            }

          printf("\n");
          {
              ret = gnutls_priority_certificate_type_list (pcache, &list);

              printf ("Certificate types: ");
              if (ret == 0) printf("none\n");
              for (i = 0; i < (unsigned)ret; i++)
                {
                    printf ("CTYPE-%s",
                            gnutls_certificate_type_get_name (list[i]));
                    if (i+1!=(unsigned)ret)
                        printf (", ");
                    else
                        printf ("\n");
                }
          }

          {
              ret = gnutls_priority_protocol_list (pcache, &list);

              printf ("Protocols: ");
              if (ret == 0) printf("none\n");
              for (i = 0; i < (unsigned)ret; i++)
                {
                    printf ("VERS-%s", gnutls_protocol_get_name (list[i]));
                    if (i+1!=(unsigned)ret)
                        printf (", ");
                    else
                        printf ("\n");
                }
          }

          {
              ret = gnutls_priority_compression_list (pcache, &list);

              printf ("Compression: ");
              if (ret == 0) printf("none\n");
              for (i = 0; i < (unsigned)ret; i++)
                {
                    printf ("COMP-%s",
                            gnutls_compression_get_name (list[i]));
                    if (i+1!=(unsigned)ret)
                        printf (", ");
                    else
                        printf ("\n");
                }
          }

          {
              ret = gnutls_priority_ecc_curve_list (pcache, &list);

              printf ("Elliptic curves: ");
              if (ret == 0) printf("none\n");
              for (i = 0; i < (unsigned)ret; i++)
                {
                    printf ("CURVE-%s",
                            gnutls_ecc_curve_get_name (list[i]));
                    if (i+1!=(unsigned)ret)
                        printf (", ");
                    else
                        printf ("\n");
                }
          }

          {
              ret = gnutls_priority_sign_list (pcache, &list);

              printf ("PK-signatures: ");
              if (ret == 0) printf("none\n");
              for (i = 0; i < (unsigned)ret; i++)
                {
                    printf ("SIGN-%s",
                            gnutls_sign_algorithm_get_name (list[i]));
                    if (i+1!=(unsigned)ret)
                        printf (", ");
                    else
                        printf ("\n");
                }
          }

          return;
      }

    printf ("Cipher suites:\n");
    for (i = 0; (name = gnutls_cipher_suite_info
                 (i, id, &kx, &cipher, &mac, &version)); i++)
      {
          printf ("%-50s\t0x%02x, 0x%02x\t%s\n",
                  name,
                  (unsigned char) id[0], (unsigned char) id[1],
                  gnutls_protocol_get_name (version));
          if (verbose)
              printf ("\tKey exchange: %s\n\tCipher: %s\n\tMAC: %s\n\n",
                      gnutls_kx_get_name (kx),
                      gnutls_cipher_get_name (cipher),
                      gnutls_mac_get_name (mac));
      }

    printf("\n");
    {
        const gnutls_certificate_type_t *p =
            gnutls_certificate_type_list ();

        printf ("Certificate types: ");
        for (; *p; p++)
          {
              printf ("CTYPE-%s", gnutls_certificate_type_get_name (*p));
              if (*(p + 1))
                  printf (", ");
              else
                  printf ("\n");
          }
    }

    {
        const gnutls_protocol_t *p = gnutls_protocol_list ();

        printf ("Protocols: ");
        for (; *p; p++)
          {
              printf ("VERS-%s", gnutls_protocol_get_name (*p));
              if (*(p + 1))
                  printf (", ");
              else
                  printf ("\n");
          }
    }

    {
        const gnutls_cipher_algorithm_t *p = gnutls_cipher_list ();

        printf ("Ciphers: ");
        for (; *p; p++)
          {
              printf ("%s", gnutls_cipher_get_name (*p));
              if (*(p + 1))
                  printf (", ");
              else
                  printf ("\n");
          }
    }

    {
        const gnutls_mac_algorithm_t *p = gnutls_mac_list ();

        printf ("MACs: ");
        for (; *p; p++)
          {
              printf ("%s", gnutls_mac_get_name (*p));
              if (*(p + 1))
                  printf (", ");
              else
                  printf ("\n");
          }
    }

    {
        const gnutls_kx_algorithm_t *p = gnutls_kx_list ();

        printf ("Key exchange algorithms: ");
        for (; *p; p++)
          {
              printf ("%s", gnutls_kx_get_name (*p));
              if (*(p + 1))
                  printf (", ");
              else
                  printf ("\n");
          }
    }

    {
        const gnutls_compression_method_t *p = gnutls_compression_list ();

        printf ("Compression: ");
        for (; *p; p++)
          {
              printf ("COMP-%s", gnutls_compression_get_name (*p));
              if (*(p + 1))
                  printf (", ");
              else
                  printf ("\n");
          }
    }

    {
        const gnutls_ecc_curve_t *p = gnutls_ecc_curve_list ();

        printf ("Elliptic curves: ");
        for (; *p; p++)
          {
              printf ("CURVE-%s", gnutls_ecc_curve_get_name (*p));
              if (*(p + 1))
                  printf (", ");
              else
                  printf ("\n");
          }
    }

    {
        const gnutls_pk_algorithm_t *p = gnutls_pk_list ();

        printf ("Public Key Systems: ");
        for (; *p; p++)
          {
              printf ("%s", gnutls_pk_algorithm_get_name (*p));
              if (*(p + 1))
                  printf (", ");
              else
                  printf ("\n");
          }
    }

    {
        const gnutls_sign_algorithm_t *p = gnutls_sign_list ();

        printf ("PK-signatures: ");
        for (; *p; p++)
          {
              printf ("SIGN-%s", gnutls_sign_algorithm_get_name (*p));
              if (*(p + 1))
                  printf (", ");
              else
                  printf ("\n");
          }
    }
}
Beispiel #6
0
static void
print_resp(gnutls_buffer_st * str, gnutls_ocsp_resp_t resp,
	   gnutls_ocsp_print_formats_t format)
{
	int ret;
	unsigned indx;

	ret = gnutls_ocsp_resp_get_status(resp);
	if (ret < 0) {
		addf(str, "error: ocsp_resp_get_status: %s\n",
		     gnutls_strerror(ret));
		return;
	}

	adds(str, "\tResponse Status: ");
	switch (ret) {
	case GNUTLS_OCSP_RESP_SUCCESSFUL:
		adds(str, "Successful\n");
		break;

	case GNUTLS_OCSP_RESP_MALFORMEDREQUEST:
		adds(str, "malformedRequest\n");
		return;

	case GNUTLS_OCSP_RESP_INTERNALERROR:
		adds(str, "internalError\n");
		return;

	case GNUTLS_OCSP_RESP_TRYLATER:
		adds(str, "tryLater\n");
		return;

	case GNUTLS_OCSP_RESP_SIGREQUIRED:
		adds(str, "sigRequired\n");
		return;

	case GNUTLS_OCSP_RESP_UNAUTHORIZED:
		adds(str, "unauthorized\n");
		return;

	default:
		adds(str, "unknown\n");
		return;
	}

	{
		gnutls_datum_t oid;

		ret = gnutls_ocsp_resp_get_response(resp, &oid, NULL);
		if (ret < 0) {
			addf(str, "error: get_response: %s\n",
			     gnutls_strerror(ret));
			return;
		}

		adds(str, "\tResponse Type: ");
#define OCSP_BASIC "1.3.6.1.5.5.7.48.1.1"

		if (oid.size == sizeof(OCSP_BASIC)
		    && memcmp(oid.data, OCSP_BASIC, oid.size) == 0) {
			adds(str, "Basic OCSP Response\n");
			gnutls_free(oid.data);
		} else {
			addf(str, "Unknown response type (%.*s)\n",
			     oid.size, oid.data);
			gnutls_free(oid.data);
			return;
		}
	}

	/* Version. */
	{
		int version = gnutls_ocsp_resp_get_version(resp);
		if (version < 0)
			addf(str, "error: get_version: %s\n",
			     gnutls_strerror(version));
		else
			addf(str, _("\tVersion: %d\n"), version);
	}

	/* responderID */
	{
		gnutls_datum_t dn;

		ret = gnutls_ocsp_resp_get_responder(resp, &dn);
		if (ret < 0 || dn.data == NULL) {
			if (dn.data == 0) {
				ret = gnutls_ocsp_resp_get_responder_raw_id(resp, GNUTLS_OCSP_RESP_ID_KEY, &dn);

				if (ret >= 0) {
					addf(str, _("\tResponder Key ID: "));
					_gnutls_buffer_hexprint(str, dn.data, dn.size);
					adds(str, "\n");
				}
				gnutls_free(dn.data);
			} else {
				addf(str, "error: get_dn: %s\n",
				     gnutls_strerror(ret));
			}
		} else {
			if (dn.data != NULL) {
				addf(str, _("\tResponder ID: %.*s\n"), dn.size,
				     dn.data);
				gnutls_free(dn.data);
			}
		}
	}

	{
		char s[42];
		size_t max = sizeof(s);
		struct tm t;
		time_t tim = gnutls_ocsp_resp_get_produced(resp);

		if (tim == (time_t) - 1)
			addf(str, "error: ocsp_resp_get_produced\n");
		else if (gmtime_r(&tim, &t) == NULL)
			addf(str, "error: gmtime_r (%ld)\n",
			     (unsigned long) tim);
		else if (strftime(s, max, "%a %b %d %H:%M:%S UTC %Y", &t)
			 == 0)
			addf(str, "error: strftime (%ld)\n",
			     (unsigned long) tim);
		else
			addf(str, _("\tProduced At: %s\n"), s);
	}

	addf(str, "\tResponses:\n");
	for (indx = 0;; indx++) {
		gnutls_digest_algorithm_t digest;
		gnutls_datum_t in, ik, sn;
		unsigned int cert_status;
		time_t this_update;
		time_t next_update;
		time_t revocation_time;
		unsigned int revocation_reason;

		ret = gnutls_ocsp_resp_get_single(resp,
						  indx,
						  &digest, &in, &ik, &sn,
						  &cert_status,
						  &this_update,
						  &next_update,
						  &revocation_time,
						  &revocation_reason);
		if (ret == GNUTLS_E_REQUESTED_DATA_NOT_AVAILABLE)
			break;
		addf(str, "\t\tCertificate ID:\n");
		if (ret != GNUTLS_E_SUCCESS) {
			addf(str, "error: get_singleresponse: %s\n",
			     gnutls_strerror(ret));
			continue;
		}
		addf(str, "\t\t\tHash Algorithm: %s\n",
		     _gnutls_digest_get_name(hash_to_entry(digest)));

		adds(str, "\t\t\tIssuer Name Hash: ");
		_gnutls_buffer_hexprint(str, in.data, in.size);
		adds(str, "\n");

		adds(str, "\t\t\tIssuer Key Hash: ");
		_gnutls_buffer_hexprint(str, ik.data, ik.size);
		adds(str, "\n");

		adds(str, "\t\t\tSerial Number: ");
		_gnutls_buffer_hexprint(str, sn.data, sn.size);
		adds(str, "\n");

		gnutls_free(in.data);
		gnutls_free(ik.data);
		gnutls_free(sn.data);

		{
			const char *p = NULL;

			switch (cert_status) {
			case GNUTLS_OCSP_CERT_GOOD:
				p = "good";
				break;

			case GNUTLS_OCSP_CERT_REVOKED:
				p = "revoked";
				break;

			case GNUTLS_OCSP_CERT_UNKNOWN:
				p = "unknown";
				break;

			default:
				addf(str,
				     "\t\tCertificate Status: unexpected value %d\n",
				     cert_status);
				break;
			}

			if (p)
				addf(str, "\t\tCertificate Status: %s\n",
				     p);
		}

		/* XXX revocation reason */

		if (cert_status == GNUTLS_OCSP_CERT_REVOKED) {
			char s[42];
			size_t max = sizeof(s);
			struct tm t;

			if (revocation_time == (time_t) - 1)
				addf(str, "error: revocation_time\n");
			else if (gmtime_r(&revocation_time, &t) == NULL)
				addf(str, "error: gmtime_r (%ld)\n",
				     (unsigned long) revocation_time);
			else if (strftime
				 (s, max, "%a %b %d %H:%M:%S UTC %Y",
				  &t) == 0)
				addf(str, "error: strftime (%ld)\n",
				     (unsigned long) revocation_time);
			else
				addf(str, _("\t\tRevocation time: %s\n"),
				     s);
		}

		{
			char s[42];
			size_t max = sizeof(s);
			struct tm t;

			if (this_update == (time_t) - 1)
				addf(str, "error: this_update\n");
			else if (gmtime_r(&this_update, &t) == NULL)
				addf(str, "error: gmtime_r (%ld)\n",
				     (unsigned long) this_update);
			else if (strftime
				 (s, max, "%a %b %d %H:%M:%S UTC %Y",
				  &t) == 0)
				addf(str, "error: strftime (%ld)\n",
				     (unsigned long) this_update);
			else
				addf(str, _("\t\tThis Update: %s\n"), s);
		}

		{
			char s[42];
			size_t max = sizeof(s);
			struct tm t;

			if (next_update != (time_t) - 1) {
				if (gmtime_r(&next_update, &t) == NULL)
					addf(str, "error: gmtime_r (%ld)\n",
					     (unsigned long) next_update);
				else if (strftime
					 (s, max, "%a %b %d %H:%M:%S UTC %Y",
					  &t) == 0)
					addf(str, "error: strftime (%ld)\n",
					     (unsigned long) next_update);
				else
					addf(str, _("\t\tNext Update: %s\n"), s);
			}
		}

		/* XXX singleRequestExtensions */
	}

	adds(str, "\tExtensions:\n");
	for (indx = 0;; indx++) {
		gnutls_datum_t oid;
		unsigned int critical;
		gnutls_datum_t data;

		ret =
		    gnutls_ocsp_resp_get_extension(resp, indx, &oid,
						   &critical, &data);
		if (ret == GNUTLS_E_REQUESTED_DATA_NOT_AVAILABLE)
			break;
		else if (ret != GNUTLS_E_SUCCESS) {
			addf(str, "error: get_extension: %s\n",
			     gnutls_strerror(ret));
			continue;
		}

		if (oid.size == sizeof(GNUTLS_OCSP_NONCE) &&
		    memcmp(oid.data, GNUTLS_OCSP_NONCE, oid.size) == 0) {
			gnutls_datum_t nonce;
			unsigned int ncrit;

			ret =
			    gnutls_ocsp_resp_get_nonce(resp, &ncrit,
						       &nonce);
			if (ret != GNUTLS_E_SUCCESS) {
				addf(str, "error: get_nonce: %s\n",
				     gnutls_strerror(ret));
			} else {
				addf(str, "\t\tNonce%s: ",
				     ncrit ? " (critical)" : "");
				_gnutls_buffer_hexprint(str, nonce.data,
							nonce.size);
				adds(str, "\n");
				gnutls_free(nonce.data);
			}
		} else {
			addf(str, "\t\tUnknown extension %s (%s):\n",
			     oid.data,
			     critical ? "critical" : "not critical");

			adds(str, _("\t\t\tASCII: "));
			_gnutls_buffer_asciiprint(str, (char *) data.data,
						  data.size);
			addf(str, "\n");

			adds(str, _("\t\t\tHexdump: "));
			_gnutls_buffer_hexprint(str, (char *) data.data,
						data.size);
			adds(str, "\n");
		}

		gnutls_free(oid.data);
		gnutls_free(data.data);
	}

	/* Signature. */
	if (format == GNUTLS_OCSP_PRINT_FULL) {
		gnutls_datum_t sig;

		ret = gnutls_ocsp_resp_get_signature_algorithm(resp);
		if (ret < 0)
			addf(str, "error: get_signature_algorithm: %s\n",
			     gnutls_strerror(ret));
		else {
			const char *name =
			    gnutls_sign_algorithm_get_name(ret);
			if (name == NULL)
				name = _("unknown");
			addf(str, _("\tSignature Algorithm: %s\n"), name);
		}
		if (ret != GNUTLS_SIGN_UNKNOWN && gnutls_sign_is_secure(ret) == 0) {
			adds(str,
			     _("warning: signed using a broken signature "
			       "algorithm that can be forged.\n"));
		}

		ret = gnutls_ocsp_resp_get_signature(resp, &sig);
		if (ret < 0)
			addf(str, "error: get_signature: %s\n",
			     gnutls_strerror(ret));
		else {
			adds(str, _("\tSignature:\n"));
			_gnutls_buffer_hexdump(str, sig.data, sig.size,
					       "\t\t");

			gnutls_free(sig.data);
		}
	}

	/* certs */
	if (format == GNUTLS_OCSP_PRINT_FULL) {
		gnutls_x509_crt_t *certs;
		size_t ncerts, i;
		gnutls_datum_t out;

		ret = gnutls_ocsp_resp_get_certs(resp, &certs, &ncerts);
		if (ret < 0)
			addf(str, "error: get_certs: %s\n",
			     gnutls_strerror(ret));
		else {
			if (ncerts > 0)
				addf(str, "\tAdditional certificates:\n");

			for (i = 0; i < ncerts; i++) {
				size_t s = 0;

				ret =
				    gnutls_x509_crt_print(certs[i],
							  GNUTLS_CRT_PRINT_FULL,
							  &out);
				if (ret < 0)
					addf(str, "error: crt_print: %s\n",
					     gnutls_strerror(ret));
				else {
					addf(str, "%.*s", out.size,
					     out.data);
					gnutls_free(out.data);
				}

				ret =
				    gnutls_x509_crt_export(certs[i],
							   GNUTLS_X509_FMT_PEM,
							   NULL, &s);
				if (ret != GNUTLS_E_SHORT_MEMORY_BUFFER)
					addf(str,
					     "error: crt_export: %s\n",
					     gnutls_strerror(ret));
				else {
					out.data = gnutls_malloc(s);
					if (out.data == NULL)
						addf(str,
						     "error: malloc: %s\n",
						     gnutls_strerror
						     (GNUTLS_E_MEMORY_ERROR));
					else {
						ret =
						    gnutls_x509_crt_export
						    (certs[i],
						     GNUTLS_X509_FMT_PEM,
						     out.data, &s);
						if (ret < 0)
							addf(str,
							     "error: crt_export: %s\n",
							     gnutls_strerror
							     (ret));
						else {
							out.size = s;
							addf(str, "%.*s",
							     out.size,
							     out.data);
						}
						gnutls_free(out.data);
					}
				}

				gnutls_x509_crt_deinit(certs[i]);
			}
			gnutls_free(certs);
		}
	}
}
Beispiel #7
0
bool CTlsSocket::ExtractCert(const void* in, CCertificate& out)
{
	const gnutls_datum_t* datum = reinterpret_cast<const gnutls_datum_t*>(in);
	
	gnutls_x509_crt_t cert;
	if (gnutls_x509_crt_init(&cert))
	{
		m_pOwner->LogMessage(::Error, _("Could not initialize structure for peer certificates, gnutls_x509_crt_init failed"));
		return false;
	}

	if (gnutls_x509_crt_import(cert, datum, GNUTLS_X509_FMT_DER))
	{
		m_pOwner->LogMessage(::Error, _("Could not import peer certificates, gnutls_x509_crt_import failed"));
		gnutls_x509_crt_deinit(cert);
		return false;
	}

	wxDateTime expirationTime = gnutls_x509_crt_get_expiration_time(cert);
	wxDateTime activationTime = gnutls_x509_crt_get_activation_time(cert);

	// Get the serial number of the certificate
	unsigned char buffer[40];
	size_t size = sizeof(buffer);
	int res = gnutls_x509_crt_get_serial(cert, buffer, &size);
	if( res != 0 ) {
		size = 0;
	}

	wxString serial = bin2hex(buffer, size);

	unsigned int pkBits;
	int pkAlgo = gnutls_x509_crt_get_pk_algorithm(cert, &pkBits);
	wxString pkAlgoName;
	if (pkAlgo >= 0)
	{
		const char* pAlgo = gnutls_pk_algorithm_get_name((gnutls_pk_algorithm_t)pkAlgo);
		if (pAlgo)
			pkAlgoName = wxString(pAlgo, wxConvUTF8);
	}

	int signAlgo = gnutls_x509_crt_get_signature_algorithm(cert);
	wxString signAlgoName;
	if (signAlgo >= 0)
	{
		const char* pAlgo = gnutls_sign_algorithm_get_name((gnutls_sign_algorithm_t)signAlgo);
		if (pAlgo)
			signAlgoName = wxString(pAlgo, wxConvUTF8);
	}

	wxString subject, issuer;

	size = 0;
	res = gnutls_x509_crt_get_dn(cert, 0, &size);
	if (size)
	{
		char* dn = new char[size + 1];
		dn[size] = 0;
		if (!(res = gnutls_x509_crt_get_dn(cert, dn, &size)))
		{
			dn[size] = 0;
			subject = wxString(dn, wxConvUTF8);
		}
		else
			LogError(res, _T("gnutls_x509_crt_get_dn"));
		delete [] dn;
	}
	else
		LogError(res, _T("gnutls_x509_crt_get_dn"));
	if (subject == _T(""))
	{
		m_pOwner->LogMessage(::Error, _("Could not get distinguished name of certificate subject, gnutls_x509_get_dn failed"));
		gnutls_x509_crt_deinit(cert);
		return false;
	}

	size = 0;
	res = gnutls_x509_crt_get_issuer_dn(cert, 0, &size);
	if (size)
	{
		char* dn = new char[++size + 1];
		dn[size] = 0;
		if (!(res = gnutls_x509_crt_get_issuer_dn(cert, dn, &size)))
		{
			dn[size] = 0;
			issuer = wxString(dn, wxConvUTF8);
		}
		else
			LogError(res, _T("gnutls_x509_crt_get_issuer_dn"));
		delete [] dn;
	}
	else
		LogError(res, _T("gnutls_x509_crt_get_issuer_dn"));
	if (issuer == _T(""))
	{
		m_pOwner->LogMessage(::Error, _("Could not get distinguished name of certificate issuer, gnutls_x509_get_issuer_dn failed"));
		gnutls_x509_crt_deinit(cert);
		return false;
	}

	wxString fingerprint_md5;
	wxString fingerprint_sha1;

	unsigned char digest[100];
	size = sizeof(digest) - 1;
	if (!gnutls_x509_crt_get_fingerprint(cert, GNUTLS_DIG_MD5, digest, &size))
	{
		digest[size] = 0;
		fingerprint_md5 = bin2hex(digest, size);
	}
	size = sizeof(digest) - 1;
	if (!gnutls_x509_crt_get_fingerprint(cert, GNUTLS_DIG_SHA1, digest, &size))
	{
		digest[size] = 0;
		fingerprint_sha1 = bin2hex(digest, size);
	}

	gnutls_x509_crt_deinit(cert);

	out = CCertificate(
		datum->data, datum->size,
		activationTime, expirationTime,
		serial,
		pkAlgoName, pkBits,
		signAlgoName,
		fingerprint_md5,
		fingerprint_sha1,
		subject,
		issuer);

	return true;
}
Beispiel #8
0
void
print_list (int verbose)
{
  {
    size_t i;
    const char *name;
    char id[2];
    gnutls_kx_algorithm_t kx;
    gnutls_cipher_algorithm_t cipher;
    gnutls_mac_algorithm_t mac;
    gnutls_protocol_t version;

    printf ("Cipher suites:\n");
    for (i = 0; (name = gnutls_cipher_suite_info
                 (i, id, &kx, &cipher, &mac, &version)); i++)
      {
        printf ("%-50s\t0x%02x, 0x%02x\t%s\n",
                name,
                (unsigned char) id[0], (unsigned char) id[1],
                gnutls_protocol_get_name (version));
        if (verbose)
          printf ("\tKey exchange: %s\n\tCipher: %s\n\tMAC: %s\n\n",
                  gnutls_kx_get_name (kx),
                  gnutls_cipher_get_name (cipher), gnutls_mac_get_name (mac));
      }
  }

  {
    const gnutls_certificate_type_t *p = gnutls_certificate_type_list ();

    printf ("Certificate types: ");
    for (; *p; p++)
      {
        printf ("%s", gnutls_certificate_type_get_name (*p));
        if (*(p + 1))
          printf (", ");
        else
          printf ("\n");
      }
  }

  {
    const gnutls_protocol_t *p = gnutls_protocol_list ();

    printf ("Protocols: ");
    for (; *p; p++)
      {
        printf ("%s", gnutls_protocol_get_name (*p));
        if (*(p + 1))
          printf (", ");
        else
          printf ("\n");
      }
  }

  {
    const gnutls_cipher_algorithm_t *p = gnutls_cipher_list ();

    printf ("Ciphers: ");
    for (; *p; p++)
      {
        printf ("%s", gnutls_cipher_get_name (*p));
        if (*(p + 1))
          printf (", ");
        else
          printf ("\n");
      }
  }

  {
    const gnutls_mac_algorithm_t *p = gnutls_mac_list ();

    printf ("MACs: ");
    for (; *p; p++)
      {
        printf ("%s", gnutls_mac_get_name (*p));
        if (*(p + 1))
          printf (", ");
        else
          printf ("\n");
      }
  }

  {
    const gnutls_kx_algorithm_t *p = gnutls_kx_list ();

    printf ("Key exchange algorithms: ");
    for (; *p; p++)
      {
        printf ("%s", gnutls_kx_get_name (*p));
        if (*(p + 1))
          printf (", ");
        else
          printf ("\n");
      }
  }

  {
    const gnutls_compression_method_t *p = gnutls_compression_list ();

    printf ("Compression: ");
    for (; *p; p++)
      {
        printf ("%s", gnutls_compression_get_name (*p));
        if (*(p + 1))
          printf (", ");
        else
          printf ("\n");
      }
  }

  {
    const gnutls_pk_algorithm_t *p = gnutls_pk_list ();

    printf ("Public Key Systems: ");
    for (; *p; p++)
      {
        printf ("%s", gnutls_pk_algorithm_get_name (*p));
        if (*(p + 1))
          printf (", ");
        else
          printf ("\n");
      }
  }

  {
    const gnutls_sign_algorithm_t *p = gnutls_sign_list ();

    printf ("PK-signatures: ");
    for (; *p; p++)
      {
        printf ("%s", gnutls_sign_algorithm_get_name (*p));
        if (*(p + 1))
          printf (", ");
        else
          printf ("\n");
      }
  }
}
Beispiel #9
0
/* Generates a signature of all the random data and the parameters.
 * Used in DHE_* ciphersuites.
 */
int
_gnutls_handshake_sign_data(gnutls_session_t session,
			    gnutls_pcert_st * cert, gnutls_privkey_t pkey,
			    gnutls_datum_t * params,
			    gnutls_datum_t * signature,
			    gnutls_sign_algorithm_t * sign_algo)
{
	gnutls_datum_t dconcat;
	int ret;
	digest_hd_st td_sha;
	uint8_t concat[MAX_SIG_SIZE];
	const version_entry_st *ver = get_version(session);
	const mac_entry_st *hash_algo;

	*sign_algo = _gnutls_session_get_sign_algo(session, cert);
	if (*sign_algo == GNUTLS_SIGN_UNKNOWN) {
		gnutls_assert();
		return GNUTLS_E_UNKNOWN_PK_ALGORITHM;
	}

	gnutls_sign_algorithm_set_server(session, *sign_algo);

	hash_algo =
	    hash_to_entry(gnutls_sign_get_hash_algorithm(*sign_algo));
	if (hash_algo == NULL)
		return gnutls_assert_val(GNUTLS_E_UNKNOWN_HASH_ALGORITHM);

	_gnutls_handshake_log
	    ("HSK[%p]: signing handshake data: using %s\n", session,
	     gnutls_sign_algorithm_get_name(*sign_algo));

	ret = _gnutls_hash_init(&td_sha, hash_algo);
	if (ret < 0) {
		gnutls_assert();
		return ret;
	}

	_gnutls_hash(&td_sha, session->security_parameters.client_random,
		     GNUTLS_RANDOM_SIZE);
	_gnutls_hash(&td_sha, session->security_parameters.server_random,
		     GNUTLS_RANDOM_SIZE);
	_gnutls_hash(&td_sha, params->data, params->size);

	switch (gnutls_privkey_get_pk_algorithm(pkey, NULL)) {
	case GNUTLS_PK_RSA:
		if (!_gnutls_version_has_selectable_sighash(ver)) {
			digest_hd_st td_md5;

			ret =
			    _gnutls_hash_init(&td_md5,
					      hash_to_entry
					      (GNUTLS_DIG_MD5));
			if (ret < 0) {
				gnutls_assert();
				return ret;
			}

			_gnutls_hash(&td_md5,
				     session->security_parameters.
				     client_random, GNUTLS_RANDOM_SIZE);
			_gnutls_hash(&td_md5,
				     session->security_parameters.
				     server_random, GNUTLS_RANDOM_SIZE);
			_gnutls_hash(&td_md5, params->data, params->size);

			_gnutls_hash_deinit(&td_md5, concat);
			_gnutls_hash_deinit(&td_sha, &concat[16]);

			dconcat.data = concat;
			dconcat.size = 36;
		} else {	/* TLS 1.2 way */

			_gnutls_hash_deinit(&td_sha, concat);

			dconcat.data = concat;
			dconcat.size =
			    _gnutls_hash_get_algo_len(hash_algo);
		}
		break;
	case GNUTLS_PK_DSA:
	case GNUTLS_PK_EC:
		_gnutls_hash_deinit(&td_sha, concat);

		if (!IS_SHA((gnutls_digest_algorithm_t)hash_algo->id)) {
			gnutls_assert();
			return GNUTLS_E_INTERNAL_ERROR;
		}
		dconcat.data = concat;
		dconcat.size = _gnutls_hash_get_algo_len(hash_algo);
		break;

	default:
		gnutls_assert();
		_gnutls_hash_deinit(&td_sha, NULL);
		return GNUTLS_E_INTERNAL_ERROR;
	}

	ret =
	    sign_tls_hash(session, hash_algo, cert, pkey, &dconcat,
			  signature);
	if (ret < 0) {
		gnutls_assert();
	}

	return ret;

}
Beispiel #10
0
/* Verifies a TLS signature (like the one in the client certificate
 * verify message). 
 */
int
_gnutls_handshake_verify_crt_vrfy(gnutls_session_t session,
				  gnutls_pcert_st * cert,
				  gnutls_datum_t * signature,
				  gnutls_sign_algorithm_t sign_algo)
{
	int ret;
	uint8_t concat[MAX_SIG_SIZE];
	digest_hd_st td_md5;
	digest_hd_st td_sha;
	gnutls_datum_t dconcat;
	const version_entry_st *ver = get_version(session);

	_gnutls_handshake_log("HSK[%p]: verify cert vrfy: using %s\n",
			      session,
			      gnutls_sign_algorithm_get_name(sign_algo));

	if (unlikely(ver == NULL))
		return gnutls_assert_val(GNUTLS_E_INTERNAL_ERROR);

	if (_gnutls_version_has_selectable_sighash(ver))
		return _gnutls_handshake_verify_crt_vrfy12(session, cert,
							   signature,
							   sign_algo);

	ret = _gnutls_hash_init(&td_md5, hash_to_entry(GNUTLS_DIG_MD5));
	if (ret < 0) {
		gnutls_assert();
		return ret;
	}

	ret = _gnutls_hash_init(&td_sha, hash_to_entry(GNUTLS_DIG_SHA1));
	if (ret < 0) {
		gnutls_assert();
		_gnutls_hash_deinit(&td_md5, NULL);
		return GNUTLS_E_HASH_FAILED;
	}

	_gnutls_hash(&td_sha,
		     session->internals.handshake_hash_buffer.data,
		     session->internals.handshake_hash_buffer_prev_len);
	_gnutls_hash(&td_md5,
		     session->internals.handshake_hash_buffer.data,
		     session->internals.handshake_hash_buffer_prev_len);

	if (ver->id == GNUTLS_SSL3) {
		ret = _gnutls_generate_master(session, 1);
		if (ret < 0) {
			_gnutls_hash_deinit(&td_md5, NULL);
			_gnutls_hash_deinit(&td_sha, NULL);
			return gnutls_assert_val(ret);
		}

		ret = _gnutls_mac_deinit_ssl3_handshake(&td_md5, concat,
							session->security_parameters.
							master_secret,
							GNUTLS_MASTER_SIZE);
		if (ret < 0) {
			_gnutls_hash_deinit(&td_sha, NULL);
			return gnutls_assert_val(ret);
		}

		ret =
		    _gnutls_mac_deinit_ssl3_handshake(&td_sha, &concat[16],
						      session->security_parameters.
						      master_secret,
						      GNUTLS_MASTER_SIZE);
		if (ret < 0) {
			return gnutls_assert_val(ret);
		}
	} else {
		_gnutls_hash_deinit(&td_md5, concat);
		_gnutls_hash_deinit(&td_sha, &concat[16]);
	}

	dconcat.data = concat;
	dconcat.size = 20 + 16;	/* md5+ sha */

	ret =
	    verify_tls_hash(session, ver, cert, &dconcat, signature, 16,
			    GNUTLS_SIGN_UNKNOWN,
			    gnutls_pubkey_get_pk_algorithm(cert->pubkey,
							   NULL));
	if (ret < 0) {
		gnutls_assert();
		return ret;
	}

	return ret;
}
Beispiel #11
0
/* Generates a signature of all the random data and the parameters.
 * Used in DHE_* ciphersuites.
 */
int
_gnutls_handshake_verify_data(gnutls_session_t session,
			      gnutls_pcert_st * cert,
			      const gnutls_datum_t * params,
			      gnutls_datum_t * signature,
			      gnutls_sign_algorithm_t sign_algo)
{
	gnutls_datum_t dconcat;
	int ret;
	digest_hd_st td_md5;
	digest_hd_st td_sha;
	uint8_t concat[MAX_SIG_SIZE];
	const version_entry_st *ver = get_version(session);
	gnutls_digest_algorithm_t hash_algo;
	const mac_entry_st *me;

	if (_gnutls_version_has_selectable_sighash(ver)) {
		_gnutls_handshake_log
		    ("HSK[%p]: verify handshake data: using %s\n", session,
		     gnutls_sign_algorithm_get_name(sign_algo));

		ret =
		    _gnutls_pubkey_compatible_with_sig(session,
						       cert->pubkey, ver,
						       sign_algo);
		if (ret < 0)
			return gnutls_assert_val(ret);

		ret =
		    _gnutls_session_sign_algo_enabled(session, sign_algo);
		if (ret < 0)
			return gnutls_assert_val(ret);

		hash_algo = gnutls_sign_get_hash_algorithm(sign_algo);
		me = hash_to_entry(hash_algo);
	} else {
		me = hash_to_entry(GNUTLS_DIG_MD5);
		ret = _gnutls_hash_init(&td_md5, me);
		if (ret < 0) {
			gnutls_assert();
			return ret;
		}

		_gnutls_hash(&td_md5,
			     session->security_parameters.client_random,
			     GNUTLS_RANDOM_SIZE);
		_gnutls_hash(&td_md5,
			     session->security_parameters.server_random,
			     GNUTLS_RANDOM_SIZE);
		_gnutls_hash(&td_md5, params->data, params->size);

		me = hash_to_entry(GNUTLS_DIG_SHA1);
	}

	ret = _gnutls_hash_init(&td_sha, me);
	if (ret < 0) {
		gnutls_assert();
		if (!_gnutls_version_has_selectable_sighash(ver))
			_gnutls_hash_deinit(&td_md5, NULL);
		return ret;
	}

	_gnutls_hash(&td_sha, session->security_parameters.client_random,
		     GNUTLS_RANDOM_SIZE);
	_gnutls_hash(&td_sha, session->security_parameters.server_random,
		     GNUTLS_RANDOM_SIZE);
	_gnutls_hash(&td_sha, params->data, params->size);

	if (!_gnutls_version_has_selectable_sighash(ver)) {
		_gnutls_hash_deinit(&td_md5, concat);
		_gnutls_hash_deinit(&td_sha, &concat[16]);
		dconcat.data = concat;
		dconcat.size = 36;
	} else {
		_gnutls_hash_deinit(&td_sha, concat);

		dconcat.data = concat;
		dconcat.size = _gnutls_hash_get_algo_len(me);
	}

	ret = verify_tls_hash(session, ver, cert, &dconcat, signature,
			      dconcat.size - _gnutls_hash_get_algo_len(me),
			      sign_algo,
			      gnutls_sign_get_pk_algorithm(sign_algo));
	if (ret < 0) {
		gnutls_assert();
		return ret;
	}

	return ret;

}
Beispiel #12
0
/* the same as _gnutls_handshake_sign_cert_vrfy except that it is made for TLS 1.2
 */
static int
_gnutls_handshake_sign_cert_vrfy12 (gnutls_session_t session,
				    gnutls_cert * cert, gnutls_privkey * pkey,
				    gnutls_datum_t * signature)
{
  gnutls_datum_t dconcat;
  int ret;
  opaque concat[MAX_SIG_SIZE];
  digest_hd_st td;
  gnutls_sign_algorithm_t sign_algo;
  gnutls_digest_algorithm_t hash_algo;
  digest_hd_st *handshake_td;

  handshake_td = &session->internals.handshake_mac_handle.tls12.sha1;
  hash_algo = handshake_td->algorithm;
  sign_algo = _gnutls_x509_pk_to_sign (cert->subject_pk_algorithm, hash_algo);

  /* The idea here is to try signing with the one of the algorithms
   * that have been initiated at handshake (SHA1, SHA256). If they
   * are not requested by peer... tough luck
   */
  ret = _gnutls_session_sign_algo_requested (session, sign_algo);
  if (sign_algo == GNUTLS_SIGN_UNKNOWN || ret < 0)
    {
      handshake_td = &session->internals.handshake_mac_handle.tls12.sha256;
      hash_algo = handshake_td->algorithm;
      sign_algo =
	_gnutls_x509_pk_to_sign (cert->subject_pk_algorithm, hash_algo);
      if (sign_algo == GNUTLS_SIGN_UNKNOWN)
	{
	  gnutls_assert ();
	  return GNUTLS_E_UNSUPPORTED_SIGNATURE_ALGORITHM;
	}

      ret = _gnutls_session_sign_algo_requested (session, sign_algo);
      if (ret < 0)
	{
	  gnutls_assert ();
	  _gnutls_x509_log
	    ("Server did not allow either '%s' or '%s' for signing\n",
	     gnutls_mac_get_name (hash_algo),
	     gnutls_mac_get_name (session->internals.handshake_mac_handle.
				  tls12.sha1.algorithm));
	  return ret;
	}
    }

  _gnutls_x509_log ("sign handshake cert vrfy: picked %s with %s\n",
		    gnutls_sign_algorithm_get_name (sign_algo),
		    gnutls_mac_get_name (hash_algo));

  ret = _gnutls_hash_copy (&td, handshake_td);
  if (ret < 0)
    {
      gnutls_assert ();
      return ret;
    }

  _gnutls_hash_deinit (&td, concat);

  dconcat.data = concat;
  dconcat.size = _gnutls_hash_get_algo_len (hash_algo);

  ret = _gnutls_tls_sign (session, cert, pkey, &dconcat, signature);
  if (ret < 0)
    {
      gnutls_assert ();
      return ret;
    }

  return sign_algo;
}
Beispiel #13
0
/* Generates a signature of all the random data and the parameters.
 * Used in DHE_* ciphersuites.
 */
int
_gnutls_handshake_sign_data (gnutls_session_t session, gnutls_pcert_st* cert,
                             gnutls_privkey_t pkey, gnutls_datum_t * params,
                             gnutls_datum_t * signature,
                             gnutls_sign_algorithm_t * sign_algo)
{
  gnutls_datum_t dconcat;
  int ret;
  digest_hd_st td_sha;
  opaque concat[MAX_SIG_SIZE];
  gnutls_protocol_t ver = gnutls_protocol_get_version (session);
  gnutls_digest_algorithm_t hash_algo;

  *sign_algo =
    _gnutls_session_get_sign_algo (session, cert);
  if (*sign_algo == GNUTLS_SIGN_UNKNOWN)
    {
      gnutls_assert ();
      return GNUTLS_E_UNKNOWN_PK_ALGORITHM;
    }

  hash_algo = _gnutls_sign_get_hash_algorithm (*sign_algo);

  _gnutls_handshake_log ("HSK[%p]: signing handshake data: using %s\n",
                    session, gnutls_sign_algorithm_get_name (*sign_algo));

  ret = _gnutls_hash_init (&td_sha, hash_algo);
  if (ret < 0)
    {
      gnutls_assert ();
      return ret;
    }

  _gnutls_hash (&td_sha, session->security_parameters.client_random,
                GNUTLS_RANDOM_SIZE);
  _gnutls_hash (&td_sha, session->security_parameters.server_random,
                GNUTLS_RANDOM_SIZE);
  _gnutls_hash (&td_sha, params->data, params->size);

  switch (gnutls_pubkey_get_pk_algorithm(cert->pubkey, NULL))
    {
    case GNUTLS_PK_RSA:
      if (!_gnutls_version_has_selectable_sighash (ver))
        {
          digest_hd_st td_md5;

          ret = _gnutls_hash_init (&td_md5, GNUTLS_MAC_MD5);
          if (ret < 0)
            {
              gnutls_assert ();
              return ret;
            }

          _gnutls_hash (&td_md5, session->security_parameters.client_random,
                        GNUTLS_RANDOM_SIZE);
          _gnutls_hash (&td_md5, session->security_parameters.server_random,
                        GNUTLS_RANDOM_SIZE);
          _gnutls_hash (&td_md5, params->data, params->size);

          _gnutls_hash_deinit (&td_md5, concat);
          _gnutls_hash_deinit (&td_sha, &concat[16]);

          dconcat.data = concat;
          dconcat.size = 36;
        }
      else
        { /* TLS 1.2 way */

          _gnutls_hash_deinit (&td_sha, concat);

          dconcat.data = concat;
          dconcat.size = _gnutls_hash_get_algo_len (hash_algo);
        }
      break;
    case GNUTLS_PK_DSA:
      _gnutls_hash_deinit (&td_sha, concat);

      if ((hash_algo != GNUTLS_DIG_SHA1) && (hash_algo != GNUTLS_DIG_SHA224)
          && (hash_algo != GNUTLS_DIG_SHA256))
        {
          gnutls_assert ();
          return GNUTLS_E_INTERNAL_ERROR;
        }
      dconcat.data = concat;
      dconcat.size = _gnutls_hash_get_algo_len (hash_algo);
      break;

    default:
      gnutls_assert ();
      _gnutls_hash_deinit (&td_sha, NULL);
      return GNUTLS_E_INTERNAL_ERROR;
    }

  ret = sign_tls_hash (session, hash_algo, cert, pkey, &dconcat, signature);
  if (ret < 0)
    {
      gnutls_assert ();
    }

  return ret;

}
Beispiel #14
0
/* Verifies a TLS signature (like the one in the client certificate
 * verify message). 
 */
int
_gnutls_handshake_verify_cert_vrfy (gnutls_session_t session,
                                    gnutls_pcert_st *cert,
                                    gnutls_datum_t * signature,
                                    gnutls_sign_algorithm_t sign_algo)
{
  int ret;
  opaque concat[MAX_SIG_SIZE];
  digest_hd_st td_md5;
  digest_hd_st td_sha;
  gnutls_datum_t dconcat;
  gnutls_protocol_t ver = gnutls_protocol_get_version (session);

  _gnutls_handshake_log ("HSK[%p]: verify cert vrfy: using %s\n",
                    session, gnutls_sign_algorithm_get_name (sign_algo));

  if (session->security_parameters.handshake_mac_handle_type ==
      HANDSHAKE_MAC_TYPE_12)
    {
      return _gnutls_handshake_verify_cert_vrfy12 (session, cert, signature,
                                                   sign_algo);
    }
  else if (session->security_parameters.handshake_mac_handle_type !=
           HANDSHAKE_MAC_TYPE_10)
    {
      gnutls_assert ();
      return GNUTLS_E_INTERNAL_ERROR;
    }

  ret =
    _gnutls_hash_copy (&td_md5,
                       &session->internals.handshake_mac_handle.tls10.md5);
  if (ret < 0)
    {
      gnutls_assert ();
      return ret;
    }

  ret =
    _gnutls_hash_copy (&td_sha,
                       &session->internals.handshake_mac_handle.tls10.sha);
  if (ret < 0)
    {
      gnutls_assert ();
      _gnutls_hash_deinit (&td_md5, NULL);
      return GNUTLS_E_HASH_FAILED;
    }

  if (ver == GNUTLS_SSL3)
    {
      ret = _gnutls_generate_master (session, 1);
      if (ret < 0)
        {
          _gnutls_hash_deinit (&td_md5, NULL);
          _gnutls_hash_deinit (&td_sha, NULL);
          return gnutls_assert_val(ret);
        }

      ret = _gnutls_mac_deinit_ssl3_handshake (&td_md5, concat,
                                         session->
                                         security_parameters.master_secret,
                                         GNUTLS_MASTER_SIZE);
      if (ret < 0)
        {
          _gnutls_hash_deinit (&td_sha, NULL);
          return gnutls_assert_val(ret);
        }

      ret = _gnutls_mac_deinit_ssl3_handshake (&td_sha, &concat[16],
                                         session->
                                         security_parameters.master_secret,
                                         GNUTLS_MASTER_SIZE);
      if (ret < 0)
        {
          return gnutls_assert_val(ret);
        }
    }
  else
    {
      _gnutls_hash_deinit (&td_md5, concat);
      _gnutls_hash_deinit (&td_sha, &concat[16]);
    }

  dconcat.data = concat;
  dconcat.size = 20 + 16;       /* md5+ sha */

  ret =
    verify_tls_hash (ver, cert, &dconcat, signature, 16,
                        gnutls_pubkey_get_pk_algorithm(cert->pubkey, NULL));
  if (ret < 0)
    {
      gnutls_assert ();
      return ret;
    }

  return ret;

}