예제 #1
0
int
pk_hash_data(gnutls_pk_algorithm_t pk, const mac_entry_st * hash,
	     gnutls_pk_params_st * params,
	     const gnutls_datum_t * data, gnutls_datum_t * digest)
{
	int ret;

	digest->size = _gnutls_hash_get_algo_len(hash);
	digest->data = gnutls_malloc(digest->size);
	if (digest->data == NULL) {
		gnutls_assert();
		return GNUTLS_E_MEMORY_ERROR;
	}

	ret =
	    _gnutls_hash_fast((gnutls_digest_algorithm_t)hash->id, data->data, data->size,
			      digest->data);
	if (ret < 0) {
		gnutls_assert();
		goto cleanup;
	}

	return 0;

      cleanup:
	gnutls_free(digest->data);
	return ret;
}
예제 #2
0
/**
 * gnutls_fingerprint:
 * @algo: is a digest algorithm
 * @data: is the data
 * @result: is the place where the result will be copied (may be null).
 * @result_size: should hold the size of the result. The actual size
 * of the returned result will also be copied there.
 *
 * This function will calculate a fingerprint (actually a hash), of
 * the given data.  The result is not printable data.  You should
 * convert it to hex, or to something else printable.
 *
 * This is the usual way to calculate a fingerprint of an X.509 DER
 * encoded certificate.  Note however that the fingerprint of an
 * OpenPGP certificate is not just a hash and cannot be calculated with this
 * function.
 *
 * Returns: On success, %GNUTLS_E_SUCCESS (0) is returned, otherwise
 *   an error code is returned.
 **/
int
gnutls_fingerprint(gnutls_digest_algorithm_t algo,
		   const gnutls_datum_t * data, void *result,
		   size_t * result_size)
{
	int ret;
	int hash_len = _gnutls_hash_get_algo_len(hash_to_entry(algo));

	if (hash_len < 0 || (unsigned) hash_len > *result_size
	    || result == NULL) {
		*result_size = hash_len;
		return GNUTLS_E_SHORT_MEMORY_BUFFER;
	}
	*result_size = hash_len;

	if (result) {
		ret =
		    _gnutls_hash_fast(algo, data->data, data->size,
				      result);
		if (ret < 0)
			return gnutls_assert_val(ret);
	}

	return 0;
}
예제 #3
0
unsigned char *
RIPEMD160 (const unsigned char *buf, unsigned long len, unsigned char *md)
{
  if (!md)
    return NULL;

  _gnutls_hash_fast (GNUTLS_DIG_RMD160, buf, len, md);

  return md;
}
예제 #4
0
unsigned char *
MD5 (const unsigned char *buf, unsigned long len, unsigned char *md)
{
  if (!md)
    return NULL;

  _gnutls_hash_fast (GNUTLS_DIG_MD5, buf, len, md);

  return md;
}
예제 #5
0
파일: srp.c 프로젝트: attilamolnar/gnutls
/* This calculates the SHA1(A | B)
 * A and B will be left-padded with zeros to fill n_size.
 */
bigint_t _gnutls_calc_srp_u(bigint_t A, bigint_t B, bigint_t n)
{
	size_t b_size, a_size;
	uint8_t *holder, hd[MAX_HASH_SIZE];
	size_t holder_size, hash_size, n_size;
	int ret;
	bigint_t res;

	/* get the size of n in bytes */
	_gnutls_mpi_print(n, NULL, &n_size);

	_gnutls_mpi_print(A, NULL, &a_size);
	_gnutls_mpi_print(B, NULL, &b_size);

	if (a_size > n_size || b_size > n_size) {
		gnutls_assert();
		return NULL;	/* internal error */
	}

	holder_size = n_size + n_size;

	holder = gnutls_calloc(1, holder_size);
	if (holder == NULL)
		return NULL;

	_gnutls_mpi_print(A, &holder[n_size - a_size], &a_size);
	_gnutls_mpi_print(B, &holder[n_size + n_size - b_size], &b_size);

	ret = _gnutls_hash_fast(GNUTLS_DIG_SHA1, holder, holder_size, hd);
	if (ret < 0) {
		gnutls_free(holder);
		gnutls_assert();
		return NULL;
	}

	/* convert the bytes of hd to integer
	 */
	hash_size = 20;		/* SHA */
	ret = _gnutls_mpi_init_scan_nz(&res, hd, hash_size);
	gnutls_free(holder);

	if (ret < 0) {
		gnutls_assert();
		return NULL;
	}

	return res;
}
예제 #6
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;
}
예제 #7
0
/* this is _gnutls_handshake_verify_crt_vrfy for TLS 1.2
 */
static int
_gnutls_handshake_verify_crt_vrfy12(gnutls_session_t session,
				    gnutls_pcert_st * cert,
				    gnutls_datum_t * signature,
				    gnutls_sign_algorithm_t sign_algo)
{
	int ret;
	uint8_t concat[MAX_HASH_SIZE];
	gnutls_datum_t dconcat;
	const version_entry_st *ver = get_version(session);
	gnutls_pk_algorithm_t pk =
	    gnutls_pubkey_get_pk_algorithm(cert->pubkey, NULL);
	const mac_entry_st *me;

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

	gnutls_sign_algorithm_set_client(session, sign_algo);

	me = hash_to_entry(gnutls_sign_get_hash_algorithm(sign_algo));

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

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

	ret =
	    verify_tls_hash(session, ver, cert, &dconcat, signature, 0,
			    sign_algo, pk);
	if (ret < 0) {
		gnutls_assert();
		return ret;
	}

	return ret;

}
예제 #8
0
int
pk_hash_data (gnutls_pk_algorithm_t pk, gnutls_digest_algorithm_t hash,
              bigint_t * params,
              const gnutls_datum_t * data, gnutls_datum_t * digest)
{
  int ret;

  switch (pk)
    {
    case GNUTLS_PK_RSA:
      break;
    case GNUTLS_PK_DSA:
      if (params && hash != _gnutls_dsa_q_to_hash (params[1]))
        {
          gnutls_assert ();
          return GNUTLS_E_INVALID_REQUEST;
        }
      break;
    default:
      gnutls_assert ();
      return GNUTLS_E_INVALID_REQUEST;
    }

  digest->size = _gnutls_hash_get_algo_len (hash);
  digest->data = gnutls_malloc (digest->size);
  if (digest->data == NULL)
    {
      gnutls_assert ();
      return GNUTLS_E_MEMORY_ERROR;
    }

  ret = _gnutls_hash_fast (hash, data->data, data->size, digest->data);
  if (ret < 0)
    {
      gnutls_assert ();
      goto cleanup;
    }

  return 0;

cleanup:
  gnutls_free (digest->data);
  return ret;
}
예제 #9
0
/* ID should be:
 * 3 for MAC
 * 2 for IV
 * 1 for encryption key
 *
 * Note that this function produces different key for the
 * NULL password, and for the password with zero length.
 */
int
_gnutls_pkcs12_string_to_key(const mac_entry_st * me,
			     unsigned int id, const uint8_t * salt,
			     unsigned int salt_size, unsigned int iter,
			     const char *pw, unsigned int req_keylen,
			     uint8_t * keybuf)
{
	int rc;
	unsigned int i, j;
	digest_hd_st md;
	bigint_t num_b1 = NULL, num_ij = NULL;
	bigint_t mpi512 = NULL;
	unsigned int pwlen;
	uint8_t hash[MAX_HASH_SIZE], buf_b[64], buf_i[MAX_PASS_LEN * 2 + 64], *p;
	uint8_t d[64];
	size_t cur_keylen;
	size_t n, m, p_size, i_size;
	unsigned mac_len;
	const uint8_t buf_512[] =	/* 2^64 */
	{ 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
		0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
		0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
		0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
		0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
		0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
		0x00, 0x00, 0x00, 0x00, 0x00
	};

	cur_keylen = 0;

	if (pw == NULL)
		pwlen = 0;
	else
		pwlen = strlen(pw);

	if (pwlen > MAX_PASS_LEN) {
		gnutls_assert();
		return GNUTLS_E_INVALID_REQUEST;
	}

	if ((rc = _pkcs12_check_pass(pw, pwlen)) < 0) {
		gnutls_assert();
		return rc;
	}

	rc = _gnutls_mpi_init_scan(&mpi512, buf_512, sizeof(buf_512));
	if (rc < 0) {
		gnutls_assert();
		return rc;
	}

	/* Store salt and password in BUF_I */
	p_size = ((pwlen / 64) * 64) + 64;

	if (p_size > sizeof(buf_i) - 64)
		return gnutls_assert_val(GNUTLS_E_INVALID_REQUEST);

	p = buf_i;
	for (i = 0; i < 64; i++)
		*p++ = salt[i % salt_size];
	if (pw) {
		for (i = j = 0; i < p_size; i += 2) {
			*p++ = 0;
			*p++ = pw[j];
			if (++j > pwlen)	/* Note, that we include the trailing (0) */
				j = 0;
		}
	} else
		memset(p, 0, p_size);

	i_size = 64 + p_size;
	mac_len = _gnutls_mac_get_algo_len(me);

	for (;;) {
		rc = _gnutls_hash_init(&md, me);
		if (rc < 0) {
			gnutls_assert();
			goto cleanup;
		}
		memset(d, id & 0xff, 64);
		_gnutls_hash(&md, d, 64);
		_gnutls_hash(&md, buf_i, pw ? i_size : 64);
		_gnutls_hash_deinit(&md, hash);
		for (i = 1; i < iter; i++) {
			rc = _gnutls_hash_fast(me->id, hash, mac_len,
					       hash);
			if (rc < 0) {
				gnutls_assert();
				goto cleanup;
			}
		}
		for (i = 0; i < mac_len && cur_keylen < req_keylen; i++)
			keybuf[cur_keylen++] = hash[i];
		if (cur_keylen == req_keylen) {
			rc = 0;	/* ready */
			goto cleanup;
		}

		/* need more bytes. */
		for (i = 0; i < 64; i++)
			buf_b[i] = hash[i % mac_len];
		n = 64;
		rc = _gnutls_mpi_init_scan(&num_b1, buf_b, n);
		if (rc < 0) {
			gnutls_assert();
			goto cleanup;
		}

		rc = _gnutls_mpi_add_ui(num_b1, num_b1, 1);
		if (rc < 0) {
			gnutls_assert();
			goto cleanup;
		}
		
		for (i = 0; i < 128; i += 64) {
			n = 64;
			rc = _gnutls_mpi_init_scan(&num_ij, buf_i + i, n);
			if (rc < 0) {
				gnutls_assert();
				goto cleanup;
			}

			rc = _gnutls_mpi_addm(num_ij, num_ij, num_b1, mpi512);
			if (rc < 0) {
				gnutls_assert();
				goto cleanup;
			}

			n = 64;
#ifndef PKCS12_BROKEN_KEYGEN
			m = (_gnutls_mpi_get_nbits(num_ij) + 7) / 8;
#else
			m = n;
#endif
			memset(buf_i + i, 0, n - m);
			rc = _gnutls_mpi_print(num_ij, buf_i + i + n - m,
					       &n);
			if (rc < 0) {
				gnutls_assert();
				goto cleanup;
			}
			_gnutls_mpi_release(&num_ij);
		}
	}
      cleanup:
	_gnutls_mpi_release(&num_ij);
	_gnutls_mpi_release(&num_b1);
	_gnutls_mpi_release(&mpi512);

	return rc;
}
static int parse_commitment_line(char* line, 
                      const char* host, size_t host_len,
                      const char* service, size_t service_len,
                      time_t now,
                      const gnutls_datum_t *skey)
{
char* p, *kp;
char* savep = NULL;
size_t kp_len, phash_size;
time_t expiration;
int ret;
gnutls_digest_algorithm_t hash_algo;
uint8_t phash[MAX_HASH_SIZE];
uint8_t hphash[MAX_HASH_SIZE*2+1];

  /* read host */
  p = strtok_r(line, "|", &savep);
  if (p == NULL)
    return gnutls_assert_val(GNUTLS_E_PARSING_ERROR);
    
  if (p[0] != '*' && strcmp(p, host) != 0)
    return gnutls_assert_val(GNUTLS_E_PARSING_ERROR);

  /* read service */
  p = strtok_r(NULL, "|", &savep);
  if (p == NULL)
    return gnutls_assert_val(GNUTLS_E_PARSING_ERROR);
    
  if (p[0] != '*' && strcmp(p, service) != 0)
    return gnutls_assert_val(GNUTLS_E_PARSING_ERROR);

  /* read expiration */
  p = strtok_r(NULL, "|", &savep);
  if (p == NULL)
    return gnutls_assert_val(GNUTLS_E_PARSING_ERROR);
    
  expiration = (time_t)atol(p);
  if (expiration > 0 && now > expiration)
    return gnutls_assert_val(GNUTLS_E_EXPIRED);

  /* read hash algorithm */
  p = strtok_r(NULL, "|", &savep);
  if (p == NULL)
    return gnutls_assert_val(GNUTLS_E_PARSING_ERROR);

  hash_algo = (time_t)atol(p);
  if (_gnutls_digest_get_name(hash_algo) == NULL)
    return gnutls_assert_val(GNUTLS_E_PARSING_ERROR);

  /* read hash */
  kp = strtok_r(NULL, "|", &savep);
  if (kp == NULL)
    return gnutls_assert_val(GNUTLS_E_PARSING_ERROR);
  
  p = strpbrk(kp, "\n \r\t|");
  if (p != NULL) *p = 0;

  /* hash and hex encode */
  ret = _gnutls_hash_fast (hash_algo, skey->data, skey->size, phash);
  if (ret < 0)
    return gnutls_assert_val(ret);
    
  phash_size = _gnutls_hash_get_algo_len(hash_algo);

  p = _gnutls_bin2hex (phash, phash_size,(void*) hphash,
                         sizeof(hphash), NULL);
  if (p == NULL)
    return gnutls_assert_val(GNUTLS_E_INTERNAL_ERROR);

  kp_len = strlen(kp);
  if (kp_len != phash_size*2)
    return gnutls_assert_val(GNUTLS_E_CERTIFICATE_KEY_MISMATCH);

  if (memcmp(kp, hphash, kp_len) != 0)
    return gnutls_assert_val(GNUTLS_E_CERTIFICATE_KEY_MISMATCH);

  /* key found and matches */
  return 0;
}