コード例 #1
0
ファイル: eet_cipher.c プロジェクト: Stefan-Schmidt/efl
const void *
eet_identity_check(const void   *data_base,
                   unsigned int  data_length,
                   void        **sha1,
                   int          *sha1_length,
                   const void   *signature_base,
                   unsigned int  signature_length,
                   const void  **raw_signature_base,
                   unsigned int *raw_signature_length,
                   int          *x509_length)
{
#ifdef HAVE_SIGNATURE
   const int *header = signature_base;
   const unsigned char *sign;
   const unsigned char *cert_der;
   int sign_len;
   int cert_len;
   int magic;

   /* At least the header size */
   if (signature_length < sizeof(int) * 3)
     return NULL;

   if (!emile_cipher_init()) return NULL;

   /* Get the header */
   memcpy(&magic,    header, sizeof(int));
   memcpy(&sign_len, header+1, sizeof(int));
   memcpy(&cert_len, header+2, sizeof(int));

   magic = ntohl(magic);
   sign_len = ntohl(sign_len);
   cert_len = ntohl(cert_len);

   /* Verify the header */
   if (magic != EET_MAGIC_SIGN)
     return NULL;

   if (sign_len + cert_len + sizeof(int) * 3 > signature_length)
     return NULL;

   /* Update the signature and certificate pointer */
   sign = (unsigned char *)signature_base + sizeof(int) * 3;
   cert_der = sign + sign_len;

# ifdef HAVE_GNUTLS
   gnutls_x509_crt_t cert;
   gnutls_datum_t datum;
   gnutls_datum_t signature;
   gnutls_pubkey_t pubkey;
   unsigned char *hash;
   gcry_md_hd_t md;
   int err;

   /* Create an understanding certificate structure for gnutls */
   datum.data = (void *)cert_der;
   datum.size = cert_len;
   gnutls_x509_crt_init(&cert);
   gnutls_x509_crt_import(cert, &datum, GNUTLS_X509_FMT_DER);

   signature.data = (void *)sign;
   signature.size = sign_len;

   /* Verify the signature */
   /*
      I am waiting for my patch being accepted in GnuTLS release.
      But we now have a way to prevent double computation of SHA1.
    */
   err = gcry_md_open (&md, GCRY_MD_SHA1, 0);
   if (err < 0)
     return NULL;

   gcry_md_write(md, data_base, data_length);

   hash = gcry_md_read(md, GCRY_MD_SHA1);
   if (!hash)
     goto on_error;

   datum.size = gcry_md_get_algo_dlen(GCRY_MD_SHA1);
   datum.data = hash;

   if (gnutls_pubkey_init(&pubkey) < 0)
     goto on_error;

   if (gnutls_pubkey_import_x509(pubkey, cert, 0) < 0)
     goto on_error;

   if (gnutls_pubkey_verify_hash2(pubkey,
                                  gnutls_x509_crt_get_signature_algorithm(cert),
                                  0,
                                  &datum, &signature) < 0)
     goto on_error;

   if (sha1)
     {
        *sha1 = malloc(datum.size);
        if (!*sha1) goto on_error;

        memcpy(*sha1, hash, datum.size);
        *sha1_length = datum.size;
     }

   gcry_md_close(md);
   gnutls_x509_crt_deinit(cert);

# else /* ifdef HAVE_GNUTLS */
   const unsigned char *tmp;
   EVP_PKEY *pkey;
   X509 *x509;
#if OPENSSL_VERSION_NUMBER >= 0x10100000L && !defined(LIBRESSL_VERSION_NUMBER)
   EVP_MD_CTX *md_ctx;
#else
   EVP_MD_CTX md_ctx;
#endif
   int err;

   /* Strange but d2i_X509 seems to put 0 all over the place. */
   tmp = alloca(cert_len);
   memcpy((char *)tmp, cert_der, cert_len);
   x509 = d2i_X509(NULL, &tmp, cert_len);
   if (!x509)
     return NULL;

   /* Get public key - eay */
   pkey = X509_get_pubkey(x509);
   if (!pkey)
     {
        X509_free(x509);
        return NULL;
     }

   /* Verify the signature */
#if OPENSSL_VERSION_NUMBER >= 0x10100000L && !defined(LIBRESSL_VERSION_NUMBER)
   md_ctx = EVP_MD_CTX_new();
   EVP_VerifyInit(md_ctx, EVP_sha1());
   EVP_VerifyUpdate(md_ctx, data_base, data_length);
   err = EVP_VerifyFinal(md_ctx, sign, sign_len, pkey);
   EVP_MD_CTX_free(md_ctx);
#else
   EVP_VerifyInit(&md_ctx, EVP_sha1());
   EVP_VerifyUpdate(&md_ctx, data_base, data_length);
   err = EVP_VerifyFinal(&md_ctx, sign, sign_len, pkey);
   EVP_MD_CTX_cleanup(&md_ctx);
#endif

   X509_free(x509);
   EVP_PKEY_free(pkey);

   if (sha1)
     {
        *sha1 = NULL;
        *sha1_length = -1;
     }

   if (err != 1)
     return NULL;

# endif /* ifdef HAVE_GNUTLS */
   if (x509_length)
     *x509_length = cert_len;

   if (raw_signature_base)
     *raw_signature_base = sign;

   if (raw_signature_length)
     *raw_signature_length = sign_len;

   return cert_der;
# ifdef HAVE_GNUTLS
 on_error:
   gcry_md_close(md);
   return NULL;
# endif
#else /* ifdef HAVE_SIGNATURE */
   data_base = NULL;
   data_length = 0;
   sha1 = NULL;
   sha1_length = NULL;
   signature_base = NULL;
   signature_length = 0;
   raw_signature_base = NULL;
   raw_signature_length = NULL;
   x509_length = NULL;
   return NULL;
#endif /* ifdef HAVE_SIGNATURE */
}
コード例 #2
0
ファイル: x509sign-verify.c プロジェクト: GostCrypt/GnuTLS
void doit(void)
{
	gnutls_x509_privkey_t key;
	gnutls_x509_crt_t crt;
	gnutls_pubkey_t pubkey;
	gnutls_privkey_t privkey;
	gnutls_sign_algorithm_t sign_algo;
	gnutls_datum_t signature;
	gnutls_datum_t signature2;
	int ret;
	size_t i;

	global_init();

	gnutls_global_set_log_function(tls_log_func);
	if (debug)
		gnutls_global_set_log_level(6);

	for (i = 0; i < sizeof(key_dat) / sizeof(key_dat[0]); i++) {
		if (debug)
			success("loop %d\n", (int) i);

		ret = gnutls_x509_privkey_init(&key);
		if (ret < 0)
			fail("gnutls_x509_privkey_init\n");

		ret =
		    gnutls_x509_privkey_import(key, &key_dat[i],
						GNUTLS_X509_FMT_PEM);
		if (ret < 0)
			fail("gnutls_x509_privkey_import\n");

		ret = gnutls_pubkey_init(&pubkey);
		if (ret < 0)
			fail("gnutls_privkey_init\n");

		ret = gnutls_privkey_init(&privkey);
		if (ret < 0)
			fail("gnutls_pubkey_init\n");

		ret = gnutls_privkey_import_x509(privkey, key, 0);
		if (ret < 0)
			fail("gnutls_privkey_import_x509\n");

		ret = gnutls_privkey_sign_hash(privkey, GNUTLS_DIG_SHA1, 0,
						&hash_data, &signature2);
		if (ret < 0)
			fail("gnutls_privkey_sign_hash\n");

		ret = gnutls_privkey_sign_data(privkey, GNUTLS_DIG_SHA1, 0,
						&raw_data, &signature);
		if (ret < 0)
			fail("gnutls_x509_privkey_sign_hash\n");

		ret = gnutls_x509_crt_init(&crt);
		if (ret < 0)
			fail("gnutls_x509_crt_init\n");

		ret =
		    gnutls_x509_crt_import(crt, &cert_dat[i],
					   GNUTLS_X509_FMT_PEM);
		if (ret < 0)
			fail("gnutls_x509_crt_import\n");

		ret = gnutls_pubkey_import_x509(pubkey, crt, 0);
		if (ret < 0)
			fail("gnutls_x509_pubkey_import\n");

		ret =
		    gnutls_x509_crt_get_signature_algorithm(crt);
		if (ret != GNUTLS_SIGN_RSA_SHA1)
			fail("gnutls_crt_get_signature_algorithm\n");

		ret =
		    gnutls_pubkey_verify_hash2(pubkey, GNUTLS_SIGN_RSA_SHA1, 0, &hash_data,
					      &signature);
		if (ret < 0)
			fail("gnutls_x509_pubkey_verify_hash2\n");

		ret =
		    gnutls_pubkey_verify_hash2(pubkey, GNUTLS_SIGN_RSA_SHA1, 0, &hash_data,
					      &signature2);
		if (ret < 0)
			fail("gnutls_x509_pubkey_verify_hash-1 (hashed data)\n");

		/* should fail */
		ret =
		    gnutls_pubkey_verify_hash2(pubkey, GNUTLS_SIGN_RSA_SHA1, 0,
					      &invalid_hash_data,
					      &signature2);
		if (ret != GNUTLS_E_PK_SIG_VERIFY_FAILED)
			fail("gnutls_x509_pubkey_verify_hash-2 (hashed data)\n");

		sign_algo =
		    gnutls_pk_to_sign(gnutls_pubkey_get_pk_algorithm
				      (pubkey, NULL), GNUTLS_DIG_SHA1);

		ret =
		    gnutls_pubkey_verify_hash2(pubkey, sign_algo, 0,
						&hash_data, &signature2);
		if (ret < 0)
			fail("gnutls_x509_pubkey_verify_hash2-1 (hashed data)\n");

		/* should fail */
		ret =
		    gnutls_pubkey_verify_hash2(pubkey, sign_algo, 0,
						&invalid_hash_data,
						&signature2);
		if (ret != GNUTLS_E_PK_SIG_VERIFY_FAILED)
			fail("gnutls_x509_pubkey_verify_hash2-2 (hashed data)\n");

		/* test the raw interface */
		gnutls_free(signature.data);
		signature.data = NULL;

		if (gnutls_pubkey_get_pk_algorithm(pubkey, NULL) ==
		    GNUTLS_PK_RSA) {
			ret =
			    gnutls_privkey_sign_hash(privkey,
						     GNUTLS_DIG_SHA1,
						     GNUTLS_PRIVKEY_SIGN_FLAG_TLS1_RSA,
						     &hash_data,
						     &signature);
			if (ret < 0)
				fail("gnutls_privkey_sign_hash: %s\n",
				     gnutls_strerror(ret));

			sign_algo =
			    gnutls_pk_to_sign
			    (gnutls_pubkey_get_pk_algorithm(pubkey, NULL),
			     GNUTLS_DIG_SHA1);

			ret =
			    gnutls_pubkey_verify_hash2(pubkey, sign_algo,
							GNUTLS_PUBKEY_VERIFY_FLAG_TLS1_RSA,
							&hash_data,
							&signature);
			if (ret < 0)
				fail("gnutls_pubkey_verify_hash-3 (raw hashed data)\n");

			gnutls_free(signature.data);
			/* test the legacy API */
			ret =
			    gnutls_privkey_sign_raw_data(privkey, 0,
							 &hash_data,
							 &signature);
			if (ret < 0)
				fail("gnutls_privkey_sign_raw_data: %s\n",
				     gnutls_strerror(ret));

			ret =
			    gnutls_pubkey_verify_hash2(pubkey, sign_algo,
							GNUTLS_PUBKEY_VERIFY_FLAG_TLS1_RSA,
							&hash_data,
							&signature);
			if (ret < 0)
				fail("gnutls_pubkey_verify_hash-4 (legacy raw hashed data)\n");
		}
		gnutls_free(signature.data);
		gnutls_free(signature2.data);
		gnutls_x509_privkey_deinit(key);
		gnutls_x509_crt_deinit(crt);
		gnutls_privkey_deinit(privkey);
		gnutls_pubkey_deinit(pubkey);
	}

	gnutls_global_deinit();
}
コード例 #3
0
ファイル: gnutls_sig.c プロジェクト: Drakey83/steamlink-sdk
static int
verify_tls_hash(gnutls_session_t session,
		const version_entry_st * ver, gnutls_pcert_st * cert,
		const gnutls_datum_t * hash_concat,
		gnutls_datum_t * signature, size_t sha1pos,
		gnutls_sign_algorithm_t sign_algo,
		gnutls_pk_algorithm_t pk_algo)
{
	int ret;
	gnutls_datum_t vdata;
	unsigned int key_usage = 0, flags;

	if (cert == NULL) {
		gnutls_assert();
		return GNUTLS_E_CERTIFICATE_ERROR;
	}

	gnutls_pubkey_get_key_usage(cert->pubkey, &key_usage);

	/* If the certificate supports signing continue.
	 */
	if (key_usage != 0)
		if (!(key_usage & GNUTLS_KEY_DIGITAL_SIGNATURE)) {
			gnutls_assert();
			_gnutls_audit_log(session,
					  "Peer's certificate does not allow digital signatures. Key usage violation detected (ignored).\n");
		}

	if (pk_algo == GNUTLS_PK_UNKNOWN)
		pk_algo =
		    gnutls_pubkey_get_pk_algorithm(cert->pubkey, NULL);
	switch (pk_algo) {
	case GNUTLS_PK_RSA:

		vdata.data = hash_concat->data;
		vdata.size = hash_concat->size;

		/* verify signature */
		if (!_gnutls_version_has_selectable_sighash(ver))
			flags = GNUTLS_PUBKEY_VERIFY_FLAG_TLS_RSA;
		else
			flags = 0;
		break;
	case GNUTLS_PK_DSA:
	case GNUTLS_PK_EC:
		vdata.data = &hash_concat->data[sha1pos];
		vdata.size = hash_concat->size - sha1pos;

		flags = 0;

		break;
	default:
		gnutls_assert();
		return GNUTLS_E_INTERNAL_ERROR;
	}

	gnutls_sign_algorithm_set_server(session, sign_algo);

	ret = gnutls_pubkey_verify_hash2(cert->pubkey, sign_algo, flags,
					 &vdata, signature);

	if (ret < 0)
		return gnutls_assert_val(ret);


	return 0;
}
コード例 #4
0
ファイル: x509sign-verify.c プロジェクト: nobled/gnutls
void
doit (void)
{
  gnutls_x509_privkey_t key;
  gnutls_x509_crt_t crt;
  gnutls_pubkey_t pubkey;
  gnutls_privkey_t privkey;
  gnutls_digest_algorithm_t hash_algo;
  gnutls_sign_algorithm_t sign_algo;
  gnutls_datum_t signature;
  gnutls_datum_t signature2;
  int ret;
  size_t i;

  gnutls_global_init ();

  gnutls_global_set_log_function (tls_log_func);
  if (debug)
    gnutls_global_set_log_level (6);

  for (i = 0; i < sizeof (key_dat) / sizeof (key_dat[0]); i++)
    {
      if (debug)
        success ("loop %d\n", (int) i);

      ret = gnutls_x509_privkey_init (&key);
      if (ret < 0)
        fail ("gnutls_x509_privkey_init\n");

      ret =
        gnutls_x509_privkey_import (key, &key_dat[i], GNUTLS_X509_FMT_PEM);
      if (ret < 0)
        fail ("gnutls_x509_privkey_import\n");

      ret = gnutls_pubkey_init (&pubkey);
      if (ret < 0)
        fail ("gnutls_privkey_init\n");

      ret = gnutls_privkey_init (&privkey);
      if (ret < 0)
        fail ("gnutls_pubkey_init\n");

      ret = gnutls_privkey_import_x509 (privkey, key, 0);
      if (ret < 0)
        fail ("gnutls_privkey_import_x509\n");

      ret = gnutls_privkey_sign_hash (privkey, GNUTLS_DIG_SHA1, 0,
				      &hash_data, &signature2);
      if (ret < 0)
        fail ("gnutls_privkey_sign_hash\n");

      ret = gnutls_privkey_sign_data (privkey, GNUTLS_DIG_SHA1, 0,
				      &raw_data, &signature);
      if (ret < 0)
        fail ("gnutls_x509_privkey_sign_hash\n");

      ret = gnutls_x509_crt_init (&crt);
      if (ret < 0)
        fail ("gnutls_x509_crt_init\n");

      ret = gnutls_x509_crt_import (crt, &cert_dat[i], GNUTLS_X509_FMT_PEM);
      if (ret < 0)
        fail ("gnutls_x509_crt_import\n");

      ret =
        gnutls_pubkey_import_x509 (pubkey, crt, 0);
      if (ret < 0)
        fail ("gnutls_x509_pubkey_import\n");

      ret =
        gnutls_pubkey_get_verify_algorithm (pubkey, &signature, &hash_algo);
      if (ret < 0 || hash_algo != GNUTLS_DIG_SHA1)
        fail ("gnutls_x509_crt_get_verify_algorithm\n");

      ret = gnutls_pubkey_verify_hash (pubkey, 0, &hash_data, &signature);
      if (ret < 0)
        fail ("gnutls_x509_pubkey_verify_hash\n");

      ret =
        gnutls_pubkey_get_verify_algorithm (pubkey, &signature2, &hash_algo);
      if (ret < 0 || hash_algo != GNUTLS_DIG_SHA1)
        fail ("gnutls_x509_crt_get_verify_algorithm (hashed data)\n");

      ret = gnutls_pubkey_verify_hash (pubkey, 0, &hash_data, &signature2);
      if (ret < 0)
        fail ("gnutls_x509_pubkey_verify_hash-1 (hashed data)\n");

      /* should fail */
      ret = gnutls_pubkey_verify_hash (pubkey, 0, &invalid_hash_data, &signature2);
      if (ret != GNUTLS_E_PK_SIG_VERIFY_FAILED)
        fail ("gnutls_x509_pubkey_verify_hash-2 (hashed data)\n");
        
      sign_algo = gnutls_pk_to_sign(gnutls_pubkey_get_pk_algorithm(pubkey, NULL),
                                    GNUTLS_DIG_SHA1);

      ret = gnutls_pubkey_verify_hash2 (pubkey, sign_algo, 0, &hash_data, &signature2);
      if (ret < 0)
        fail ("gnutls_x509_pubkey_verify_hash2-1 (hashed data)\n");

      /* should fail */
      ret = gnutls_pubkey_verify_hash2 (pubkey, sign_algo, 0, &invalid_hash_data, &signature2);
      if (ret != GNUTLS_E_PK_SIG_VERIFY_FAILED)
        fail ("gnutls_x509_pubkey_verify_hash2-2 (hashed data)\n");


      gnutls_free(signature.data);
      gnutls_free(signature2.data);
      gnutls_x509_privkey_deinit (key);
      gnutls_x509_crt_deinit (crt);
      gnutls_privkey_deinit (privkey);
      gnutls_pubkey_deinit (pubkey);
    }

  gnutls_global_deinit ();
}
コード例 #5
0
static
void test_sig(gnutls_pk_algorithm_t pk, unsigned hash, unsigned bits)
{
	gnutls_pubkey_t pubkey;
	gnutls_privkey_t privkey;
	gnutls_sign_algorithm_t sign_algo;
	gnutls_datum_t signature;
	const gnutls_datum_t *hash_data;
	int ret;
	unsigned j;

	if (hash == GNUTLS_DIG_SHA1)
		hash_data = &sha1_data;
	else if (hash == GNUTLS_DIG_SHA256)
		hash_data = &sha256_data;
	else
		abort();

	sign_algo =
	    gnutls_pk_to_sign(pk, hash);

	for (j = 0; j < 100; j++) {
		ret = gnutls_pubkey_init(&pubkey);
		if (ret < 0)
			ERR(__LINE__);

		ret = gnutls_privkey_init(&privkey);
		if (ret < 0)
			ERR(__LINE__);

		ret = gnutls_privkey_generate(privkey, pk, bits, 0);
		if (ret < 0)
			ERR(__LINE__);

		ret =
		    gnutls_privkey_sign_hash(privkey, hash,
					     0, hash_data,
					     &signature);
		if (ret < 0)
			ERR(__LINE__);

		ret = gnutls_pubkey_import_privkey(pubkey, privkey, GNUTLS_KEY_DIGITAL_SIGNATURE, 0);
		if (ret < 0)
			ERR(__LINE__);

		ret =
		    gnutls_pubkey_verify_hash2(pubkey,
						sign_algo, 0,
						hash_data, &signature);
		if (ret < 0)
			ERR(__LINE__);

		/* should fail */
		ret =
		    gnutls_pubkey_verify_hash2(pubkey,
						sign_algo, 0,
						&invalid_hash_data,
						&signature);
		if (ret != GNUTLS_E_PK_SIG_VERIFY_FAILED)
			ERR(__LINE__);

		sign_algo =
		    gnutls_pk_to_sign(gnutls_pubkey_get_pk_algorithm
				      (pubkey, NULL), hash);

		ret =
		    gnutls_pubkey_verify_hash2(pubkey, sign_algo, 0,
						hash_data, &signature);
		if (ret < 0)
			ERR(__LINE__);

		/* should fail */
		ret =
		    gnutls_pubkey_verify_hash2(pubkey, sign_algo, 0,
						&invalid_hash_data,
						&signature);
		if (ret != GNUTLS_E_PK_SIG_VERIFY_FAILED)
			ERR(__LINE__);

		/* test the raw interface */
		gnutls_free(signature.data);
		signature.data = NULL;

		if (pk == GNUTLS_PK_RSA) {
			ret =
			    gnutls_privkey_sign_hash(privkey,
						     hash,
						     GNUTLS_PRIVKEY_SIGN_FLAG_TLS1_RSA,
						     hash_data,
						     &signature);
			if (ret < 0)
				ERR(__LINE__);

			sign_algo =
			    gnutls_pk_to_sign
			    (gnutls_pubkey_get_pk_algorithm
			     (pubkey, NULL), hash);

			ret =
			    gnutls_pubkey_verify_hash2(pubkey,
							sign_algo,
							GNUTLS_PUBKEY_VERIFY_FLAG_TLS1_RSA,
							hash_data,
							&signature);
			if (ret < 0)
				ERR(__LINE__);

		}
		gnutls_free(signature.data);
		gnutls_privkey_deinit(privkey);
		gnutls_pubkey_deinit(pubkey);
	}

}