コード例 #1
0
/**
 * infd_acl_account_info_check_password:
 * @info: A #InfdAclAccountInfo.
 * @password: The password to check.
 *
 * Check whether @password is the correct password to log into account.
 *
 * Returns: %TRUE if @password is correct or %FALSE otherwise.
 */
gboolean
infd_acl_account_info_check_password(const InfdAclAccountInfo* info,
                                     const gchar* password)
{
  guint password_len;
  gchar* salted_password;
  gchar* hash;
  int res;
  gchar cmp;
  guint i;

  g_return_val_if_fail(info != NULL, FALSE);
  g_return_val_if_fail(password != NULL, FALSE);

  password_len = strlen(password);
  salted_password = g_malloc(32 + password_len);

  memcpy(salted_password, info->password_salt, 16);
  memcpy(salted_password + 16, password, password_len);
  memcpy(salted_password + 16 + password_len, info->password_salt + 16, 16);

  hash = g_malloc(gnutls_hash_get_len(GNUTLS_DIG_SHA256));

  res = gnutls_hash_fast(
    GNUTLS_DIG_SHA256,
    salted_password,
    32 + password_len,
    hash
  );

  g_free(salted_password);

  if(res != GNUTLS_E_SUCCESS)
  {
    g_free(hash);
    return FALSE;
  }

  /* length-independent string compare */
  cmp = 0;
  for(i = 0; i < gnutls_hash_get_len(GNUTLS_DIG_SHA256); ++i)
    cmp |= (info->password_hash[i] ^ hash[i]);
  g_free(hash);

  if(cmp != 0)
    return FALSE;

  return TRUE;
}
コード例 #2
0
ファイル: digest.cpp プロジェクト: aberaud/ucommon
void Digest::recycle(bool bin)
{
    unsigned size = bufsize;

    if(!context || hashid == 0)
        return;

    if(!bufsize) {
        gnutls_hash_deinit((MD_CTX)context, buffer);
        context = NULL;
        gnutls_hash_init((MD_CTX *)&context, (MD_ID)hashid);
    }
    else
        Digest::reset();

    size = gnutls_hash_get_len((MD_ID)hashid);

    if(!size || !context || !hashid)
        return;

    if(bin)
        gnutls_hash((MD_CTX)context, buffer, size);
    else {
        unsigned count = 0;

        while(count < size) {
            snprintf(textbuf + (count * 2), 3, "%2.2x",
buffer[count]);
            ++count;

        }
        gnutls_hash((MD_CTX)context, textbuf, size * 2);
    }
    bufsize = 0;
}
コード例 #3
0
ファイル: hash.c プロジェクト: 01org/qemu-lite
int qcrypto_hash_bytesv(QCryptoHashAlgorithm alg,
                        const struct iovec *iov,
                        size_t niov,
                        uint8_t **result,
                        size_t *resultlen,
                        Error **errp)
{
    int i, ret;
    gnutls_hash_hd_t dig;

    if (alg >= G_N_ELEMENTS(qcrypto_hash_alg_map)) {
        error_setg(errp,
                   "Unknown hash algorithm %d",
                   alg);
        return -1;
    }

    ret = gnutls_hash_init(&dig, qcrypto_hash_alg_map[alg]);

    if (ret < 0) {
        error_setg(errp,
                   "Unable to initialize hash algorithm: %s",
                   gnutls_strerror(ret));
        return -1;
    }

    for (i = 0; i < niov; i++) {
        ret = gnutls_hash(dig, iov[i].iov_base, iov[i].iov_len);
        if (ret < 0) {
            error_setg(errp,
                       "Unable process hash data: %s",
                       gnutls_strerror(ret));
            goto error;
        }
    }

    ret = gnutls_hash_get_len(qcrypto_hash_alg_map[alg]);
    if (ret <= 0) {
        error_setg(errp,
                   "Unable to get hash length: %s",
                   gnutls_strerror(ret));
        goto error;
    }
    if (*resultlen == 0) {
        *resultlen = ret;
        *result = g_new0(uint8_t, *resultlen);
    } else if (*resultlen != ret) {
        error_setg(errp,
                   "Result buffer size %zu is smaller than hash %d",
                   *resultlen, ret);
        goto error;
    }

    gnutls_hash_deinit(dig, *result);
    return 0;

 error:
    gnutls_hash_deinit(dig, NULL);
    return -1;
}
コード例 #4
0
ファイル: digest.cpp プロジェクト: aberaud/ucommon
bool Digest::has(const char *type)
{
    MD_ID id = (MD_ID)__context::map_digest(type);

    if(!id || (gnutls_hash_get_len(id) < 1))
        return false;

    return true;
}
コード例 #5
0
Vector<uint8_t> CryptoDigest::computeHash()
{
    Vector<uint8_t> result;
    int digestLen = gnutls_hash_get_len(m_context->algorithm);
    result.resize(digestLen);

    gnutls_hash_output(m_context->hash, result.data());

    return result;
}
コード例 #6
0
ファイル: cipher.cpp プロジェクト: darcyg/ucommon
void Cipher::Key::assign(const char *text, size_t size, const unsigned char *salt, unsigned count)
{
    if(!hashid || !algoid) {
        keysize = 0;
        return;
    }

    size_t kpos = 0, ivpos = 0;
    size_t mdlen = gnutls_hash_get_len((MD_ID)hashid);
    size_t tlen = strlen(text);

    if(!hashid || !mdlen) {
        clear();
        return;
    }

    char previous[MAX_DIGEST_HASHSIZE / 8];
    unsigned char temp[MAX_DIGEST_HASHSIZE / 8];
    MD_CTX mdc;

    unsigned prior = 0;
    unsigned loop;

    if(!salt)
        salt = _salt;

    if(!count)
        count = _rounds;

    do {
        gnutls_hash_init(&mdc, (MD_ID)hashid);

        if(prior++)
            gnutls_hash(mdc, previous, mdlen);

        gnutls_hash(mdc, text, tlen);

        if(salt)
            gnutls_hash(mdc, salt, 8);

        gnutls_hash_deinit(mdc, previous);

        for(loop = 1; loop < count; ++loop) {
            memcpy(temp, previous, mdlen);
            gnutls_hash_fast((MD_ID)hashid, temp, mdlen, previous); 
        }

        size_t pos = 0;
        while(kpos < keysize && pos < mdlen)
            keybuf[kpos++] = previous[pos++];
        while(ivpos < blksize && pos < mdlen)
            ivbuf[ivpos++] = previous[pos++];
    } while(kpos < keysize || ivpos < blksize);
}
コード例 #7
0
ファイル: digest.cpp プロジェクト: aberaud/ucommon
void Digest::set(const char *type)
{
    secure::init();

    release();

    hashid = __context::map_digest(type);
    
    if(!hashid || gnutls_hash_get_len((MD_ID)hashid) < 1) {
        hashid = 0;
        return;
    }

    gnutls_hash_init((MD_CTX *)&context, (MD_ID)hashid);
}
コード例 #8
0
ファイル: digest.cpp プロジェクト: aberaud/ucommon
const unsigned char *Digest::get(void)
{
    unsigned count = 0;
    unsigned size = 0;

    if(bufsize)
        return buffer;

    if(!context || hashid == 0)
        return NULL;

    gnutls_hash_deinit((MD_CTX)context, buffer);
    size = gnutls_hash_get_len((MD_ID)hashid);
    context = NULL;
    bufsize = size;

    while(count < bufsize) {
        snprintf(textbuf + (count * 2), 3, "%2.2x",
buffer[count]);
        ++count;
    }
    return buffer;
}
コード例 #9
0
static int get_entry(liServer *srv, ocsp_response_cert_entry* entry, gnutls_ocsp_resp_t resp, unsigned int ndx) {
	int r;
	memset(entry, 0, sizeof(*entry));

	r = gnutls_ocsp_resp_get_single(
			resp, ndx, &entry->digest, &entry->issuer_name_hash, NULL, &entry->serial,
			NULL, NULL, NULL, NULL, NULL);

	if (GNUTLS_E_REQUESTED_DATA_NOT_AVAILABLE == r) return r;

	if (GNUTLS_E_SUCCESS > r) {
		ERROR(srv, "Couldn't retrieve OCSP response information for entry %u (%s): %s",
				ndx,
				gnutls_strerror_name(r), gnutls_strerror(r));
		return r;
	}

	if (0 == entry->serial.size || GNUTLS_DIG_UNKNOWN == entry->digest || entry->issuer_name_hash.size != gnutls_hash_get_len(entry->digest)) {
		ERROR(srv, "Invalid OCSP response data in entry %u", ndx);
		return GNUTLS_E_OCSP_RESPONSE_ERROR;
	}

	return GNUTLS_E_SUCCESS;
}
コード例 #10
0
ファイル: hash.c プロジェクト: apple/cups
ssize_t					/* O - Size of hash or -1 on error */
cupsHashData(const char    *algorithm,	/* I - Algorithm name */
             const void    *data,	/* I - Data to hash */
             size_t        datalen,	/* I - Length of data to hash */
             unsigned char *hash,	/* I - Hash buffer */
             size_t        hashsize)	/* I - Size of hash buffer */
{
  if (!algorithm || !data || datalen == 0 || !hash || hashsize == 0)
  {
    _cupsSetError(IPP_STATUS_ERROR_INTERNAL, _("Bad arguments to function"), 1);
    return (-1);
  }

#ifdef __APPLE__
  if (!strcmp(algorithm, "sha"))
  {
   /*
    * SHA-1...
    */

    CC_SHA1_CTX	ctx;			/* SHA-1 context */

    if (hashsize < CC_SHA1_DIGEST_LENGTH)
      goto too_small;

    CC_SHA1_Init(&ctx);
    CC_SHA1_Update(&ctx, data, (CC_LONG)datalen);
    CC_SHA1_Final(hash, &ctx);

    return (CC_SHA1_DIGEST_LENGTH);
  }
  else if (!strcmp(algorithm, "sha2-224"))
  {
    CC_SHA256_CTX	ctx;		/* SHA-224 context */

    if (hashsize < CC_SHA224_DIGEST_LENGTH)
      goto too_small;

    CC_SHA224_Init(&ctx);
    CC_SHA224_Update(&ctx, data, (CC_LONG)datalen);
    CC_SHA224_Final(hash, &ctx);

    return (CC_SHA224_DIGEST_LENGTH);
  }
  else if (!strcmp(algorithm, "sha2-256"))
  {
    CC_SHA256_CTX	ctx;		/* SHA-256 context */

    if (hashsize < CC_SHA256_DIGEST_LENGTH)
      goto too_small;

    CC_SHA256_Init(&ctx);
    CC_SHA256_Update(&ctx, data, (CC_LONG)datalen);
    CC_SHA256_Final(hash, &ctx);

    return (CC_SHA256_DIGEST_LENGTH);
  }
  else if (!strcmp(algorithm, "sha2-384"))
  {
    CC_SHA512_CTX	ctx;		/* SHA-384 context */

    if (hashsize < CC_SHA384_DIGEST_LENGTH)
      goto too_small;

    CC_SHA384_Init(&ctx);
    CC_SHA384_Update(&ctx, data, (CC_LONG)datalen);
    CC_SHA384_Final(hash, &ctx);

    return (CC_SHA384_DIGEST_LENGTH);
  }
  else if (!strcmp(algorithm, "sha2-512"))
  {
    CC_SHA512_CTX	ctx;		/* SHA-512 context */

    if (hashsize < CC_SHA512_DIGEST_LENGTH)
      goto too_small;

    CC_SHA512_Init(&ctx);
    CC_SHA512_Update(&ctx, data, (CC_LONG)datalen);
    CC_SHA512_Final(hash, &ctx);

    return (CC_SHA512_DIGEST_LENGTH);
  }
  else if (!strcmp(algorithm, "sha2-512_224"))
  {
    CC_SHA512_CTX	ctx;		/* SHA-512 context */
    unsigned char	temp[CC_SHA512_DIGEST_LENGTH];
                                        /* SHA-512 hash */

   /*
    * SHA2-512 truncated to 224 bits (28 bytes)...
    */

    if (hashsize < CC_SHA224_DIGEST_LENGTH)
      goto too_small;

    CC_SHA512_Init(&ctx);
    CC_SHA512_Update(&ctx, data, (CC_LONG)datalen);
    CC_SHA512_Final(temp, &ctx);

    memcpy(hash, temp, CC_SHA224_DIGEST_LENGTH);

    return (CC_SHA224_DIGEST_LENGTH);
  }
  else if (!strcmp(algorithm, "sha2-512_256"))
  {
    CC_SHA512_CTX	ctx;		/* SHA-512 context */
    unsigned char	temp[CC_SHA512_DIGEST_LENGTH];
                                        /* SHA-512 hash */

   /*
    * SHA2-512 truncated to 256 bits (32 bytes)...
    */

    if (hashsize < CC_SHA256_DIGEST_LENGTH)
      goto too_small;

    CC_SHA512_Init(&ctx);
    CC_SHA512_Update(&ctx, data, (CC_LONG)datalen);
    CC_SHA512_Final(temp, &ctx);

    memcpy(hash, temp, CC_SHA256_DIGEST_LENGTH);

    return (CC_SHA256_DIGEST_LENGTH);
  }

#elif defined(HAVE_GNUTLS)
  gnutls_digest_algorithm_t alg = GNUTLS_DIG_UNKNOWN;
					/* Algorithm */
  unsigned char	temp[64];		/* Temporary hash buffer */
  size_t	tempsize = 0;		/* Truncate to this size? */

  if (!strcmp(algorithm, "sha"))
    alg = GNUTLS_DIG_SHA1;
  else if (!strcmp(algorithm, "sha2-224"))
    alg = GNUTLS_DIG_SHA224;
  else if (!strcmp(algorithm, "sha2-256"))
    alg = GNUTLS_DIG_SHA256;
  else if (!strcmp(algorithm, "sha2-384"))
    alg = GNUTLS_DIG_SHA384;
  else if (!strcmp(algorithm, "sha2-512"))
    alg = GNUTLS_DIG_SHA512;
  else if (!strcmp(algorithm, "sha2-512_224"))
  {
    alg      = GNUTLS_DIG_SHA512;
    tempsize = 28;
  }
  else if (!strcmp(algorithm, "sha2-512_256"))
  {
    alg      = GNUTLS_DIG_SHA512;
    tempsize = 32;
  }

  if (alg != GNUTLS_DIG_UNKNOWN)
  {
    if (tempsize > 0)
    {
     /*
      * Truncate result to tempsize bytes...
      */

      if (hashsize < tempsize)
        goto too_small;

      gnutls_hash_fast(alg, data, datalen, temp);
      memcpy(hash, temp, tempsize);

      return ((ssize_t)tempsize);
    }

    if (hashsize < gnutls_hash_get_len(alg))
      goto too_small;

    gnutls_hash_fast(alg, data, datalen, hash);

    return (gnutls_hash_get_len(alg));
  }

#else
 /*
  * No hash support without CommonCrypto or GNU TLS...
  */

  if (hashsize < 64)
    goto too_small;
#endif /* __APPLE__ */

 /*
  * Unknown hash algorithm...
  */

  _cupsSetError(IPP_STATUS_ERROR_INTERNAL, _("Unknown hash algorithm."), 1);

  return (-1);

 /*
  * We get here if the buffer is too small.
  */

  too_small:

  _cupsSetError(IPP_STATUS_ERROR_INTERNAL, _("Hash buffer too small."), 1);
  return (-1);
}
コード例 #11
0
ファイル: danetool.c プロジェクト: attilamolnar/gnutls
static void dane_info(const char *host, const char *proto,
		      unsigned int port, unsigned int ca,
		      unsigned int domain, common_info_st * cinfo)
{
	gnutls_pubkey_t pubkey;
	gnutls_x509_crt_t crt;
	unsigned char digest[64];
	gnutls_datum_t t;
	int ret;
	unsigned int usage, selector, type;
	size_t size;

	if (proto == NULL)
		proto = "tcp";
	if (port == 0)
		port = 443;

	crt = load_cert(0, cinfo);
	if (crt != NULL && HAVE_OPT(X509)) {
		selector = 0;	/* X.509 */

		size = lbuffer_size;
		ret =
		    gnutls_x509_crt_export(crt, GNUTLS_X509_FMT_DER,
					   lbuffer, &size);
		if (ret < 0) {
			fprintf(stderr, "export error: %s\n",
				gnutls_strerror(ret));
			exit(1);
		}

		gnutls_x509_crt_deinit(crt);
	} else {		/* use public key only */

		selector = 1;

		ret = gnutls_pubkey_init(&pubkey);
		if (ret < 0) {
			fprintf(stderr, "pubkey_init: %s\n",
				gnutls_strerror(ret));
			exit(1);
		}

		if (crt != NULL) {

			ret = gnutls_pubkey_import_x509(pubkey, crt, 0);
			if (ret < 0) {
				fprintf(stderr, "pubkey_import_x509: %s\n",
					gnutls_strerror(ret));
				exit(1);
			}

			size = lbuffer_size;
			ret =
			    gnutls_pubkey_export(pubkey,
						 GNUTLS_X509_FMT_DER,
						 lbuffer, &size);
			if (ret < 0) {
				fprintf(stderr, "pubkey_export: %s\n",
					gnutls_strerror(ret));
				exit(1);
			}

			gnutls_x509_crt_deinit(crt);
		} else {
			pubkey = load_pubkey(1, cinfo);

			size = lbuffer_size;
			ret =
			    gnutls_pubkey_export(pubkey,
						 GNUTLS_X509_FMT_DER,
						 lbuffer, &size);
			if (ret < 0) {
				fprintf(stderr, "export error: %s\n",
					gnutls_strerror(ret));
				exit(1);
			}
		}

		gnutls_pubkey_deinit(pubkey);
	}

	if (default_dig != GNUTLS_DIG_SHA256
	    && default_dig != GNUTLS_DIG_SHA512) {
		if (default_dig != GNUTLS_DIG_UNKNOWN)
			fprintf(stderr,
				"Unsupported digest. Assuming SHA256.\n");
		default_dig = GNUTLS_DIG_SHA256;
	}

	ret = gnutls_hash_fast(default_dig, lbuffer, size, digest);
	if (ret < 0) {
		fprintf(stderr, "hash error: %s\n", gnutls_strerror(ret));
		exit(1);
	}

	if (default_dig == GNUTLS_DIG_SHA256)
		type = 1;
	else
		type = 2;

	/* DANE certificate classification crap */
	if (domain == 0) {
		if (ca)
			usage = 0;
		else
			usage = 1;
	} else {
		if (ca)
			usage = 2;
		else
			usage = 3;
	}

	t.data = digest;
	t.size = gnutls_hash_get_len(default_dig);

	size = lbuffer_size;
	ret = gnutls_hex_encode(&t, (void *) lbuffer, &size);
	if (ret < 0) {
		fprintf(stderr, "hex encode error: %s\n",
			gnutls_strerror(ret));
		exit(1);
	}

	fprintf(outfile, "_%u._%s.%s. IN TLSA ( %.2x %.2x %.2x %s )\n",
		port, proto, host, usage, selector, type, lbuffer);

}
コード例 #12
0
static gboolean
ssl_verify_certificate (LmSSL *ssl, const gchar *server)
{
    LmSSLBase *base;
    unsigned int        status;
    int rc;

    base = LM_SSL_BASE (ssl);

    /* This verification function uses the trusted CAs in the credentials
     * structure. So you must have installed one or more CA certificates.
     */
    rc = gnutls_certificate_verify_peers2 (ssl->gnutls_session, &status);

    if (rc == GNUTLS_E_NO_CERTIFICATE_FOUND) {
        if (base->func (ssl,
                        LM_SSL_STATUS_NO_CERT_FOUND,
                        base->func_data) != LM_SSL_RESPONSE_CONTINUE) {
            return FALSE;
        }
    }

    if (rc != 0) {
        if (base->func (ssl,
                        LM_SSL_STATUS_GENERIC_ERROR,
                        base->func_data) != LM_SSL_RESPONSE_CONTINUE) {
            return FALSE;
        }
    }

    if (rc == GNUTLS_E_NO_CERTIFICATE_FOUND) {
        if (base->func (ssl,
                        LM_SSL_STATUS_NO_CERT_FOUND,
                        base->func_data) != LM_SSL_RESPONSE_CONTINUE) {
            return FALSE;
        }
    }

    if (status & GNUTLS_CERT_INVALID
        || status & GNUTLS_CERT_REVOKED) {
        if (base->func (ssl, LM_SSL_STATUS_UNTRUSTED_CERT,
                        base->func_data) != LM_SSL_RESPONSE_CONTINUE) {
            return FALSE;
        }
    }

    if (gnutls_certificate_expiration_time_peers (ssl->gnutls_session) < time (0)) {
        if (base->func (ssl, LM_SSL_STATUS_CERT_EXPIRED,
                        base->func_data) != LM_SSL_RESPONSE_CONTINUE) {
            return FALSE;
        }
    }

    if (gnutls_certificate_activation_time_peers (ssl->gnutls_session) > time (0)) {
        if (base->func (ssl, LM_SSL_STATUS_CERT_NOT_ACTIVATED,
                        base->func_data) != LM_SSL_RESPONSE_CONTINUE) {
            return FALSE;
        }
    }

    if (gnutls_certificate_type_get (ssl->gnutls_session) == GNUTLS_CRT_X509) {
        const gnutls_datum_t* cert_list;
        guint cert_list_size;
        gnutls_digest_algorithm_t digest = GNUTLS_DIG_SHA256;
        guchar digest_bin[LM_FINGERPRINT_LENGTH];
        size_t digest_size;
        gnutls_x509_crt_t cert;

        cert_list = gnutls_certificate_get_peers (ssl->gnutls_session, &cert_list_size);
        if (cert_list == NULL) {
            if (base->func (ssl, LM_SSL_STATUS_NO_CERT_FOUND,
                            base->func_data) != LM_SSL_RESPONSE_CONTINUE) {
                return FALSE;
            }
        }

        gnutls_x509_crt_init (&cert);

        if (gnutls_x509_crt_import (cert, &cert_list[0],
                                    GNUTLS_X509_FMT_DER) != 0) {
            if (base->func (ssl, LM_SSL_STATUS_NO_CERT_FOUND,
                            base->func_data) != LM_SSL_RESPONSE_CONTINUE) {
                return FALSE;
            }
        }

        if (!gnutls_x509_crt_check_hostname (cert, server)) {
            if (base->func (ssl, LM_SSL_STATUS_CERT_HOSTNAME_MISMATCH,
                            base->func_data) != LM_SSL_RESPONSE_CONTINUE) {
                return FALSE;
            }
        }

        gnutls_x509_crt_deinit (cert);

        digest_size = gnutls_hash_get_len(digest);
        g_assert(digest_size < sizeof(digest_bin));

        if (gnutls_fingerprint (digest,
                                &cert_list[0],
                                digest_bin,
                                &digest_size) >= 0) {
            _lm_ssl_base_set_fingerprint(base, digest_bin, digest_size);
            if (_lm_ssl_base_check_fingerprint(base) != 0 &&
                base->func (ssl,
                            LM_SSL_STATUS_CERT_FINGERPRINT_MISMATCH,
                            base->func_data) != LM_SSL_RESPONSE_CONTINUE) {
                return FALSE;
            }
        }
        else if (base->func (ssl, LM_SSL_STATUS_GENERIC_ERROR,
                             base->func_data) != LM_SSL_RESPONSE_CONTINUE) {
            return FALSE;
        }
    }

    return TRUE;
}
コード例 #13
0
/**
 * infd_acl_account_info_to_xml:
 * @info: A #InfdAclAccountInfo.
 * @xml: XML node to write the account information to.
 *
 * Serializes a #InfdAclAccountInfo object into an XML node. The account
 * information can be deserialized again with
 * infd_acl_account_info_from_xml().
 */
void
infd_acl_account_info_to_xml(const InfdAclAccountInfo* info,
                             xmlNodePtr xml)
{
  guint i;

  gnutls_datum_t datum;
  size_t out_size;
  gchar* out;
  int res;

  g_return_if_fail(info != NULL);
  g_return_if_fail(xml != NULL);

  inf_acl_account_to_xml(&info->account, xml);

  for(i = 0; i < info->n_certificates; ++i)
  {
    xmlNewChild(
      xml,
      NULL,
      (const xmlChar*)"certificate",
      (const xmlChar*)info->certificates[i]
    );
  }

  if(info->password_salt != NULL)
  {
    datum.data = info->password_salt;
    datum.size = 32;

    res = gnutls_hex_encode(&datum, NULL, &out_size);
    g_assert(res == GNUTLS_E_SHORT_MEMORY_BUFFER);

    out = g_malloc(out_size + 1);
    res = gnutls_hex_encode(&datum, out, &out_size);
    g_assert(res == GNUTLS_E_SUCCESS);

    out[out_size] = '\0';
    inf_xml_util_set_attribute(xml, "password-salt", out);
    g_free(out);
  }

  if(info->password_hash != NULL)
  {
    datum.data = info->password_hash;
    datum.size = gnutls_hash_get_len(GNUTLS_DIG_SHA256);

    res = gnutls_hex_encode(&datum, NULL, &out_size);
    g_assert(res == GNUTLS_E_SHORT_MEMORY_BUFFER);

    out = g_malloc(out_size + 1);
    res = gnutls_hex_encode(&datum, out, &out_size);
    g_assert(res == GNUTLS_E_SUCCESS);

    out[out_size] = '\0';
    inf_xml_util_set_attribute(xml, "password-hash", out);
    g_free(out);
  }

  if(info->first_seen != 0)
  {
    inf_xml_util_set_attribute_double(
      xml,
      "first-seen",
      info->first_seen / 1e6
    );
  }

  if(info->last_seen != 0)
  {
    inf_xml_util_set_attribute_double(
      xml,
      "last-seen",
      info->last_seen / 1e6
    );
  }
}
コード例 #14
0
/**
 * infd_acl_account_info_from_xml:
 * @xml: The XML node from which to read the account information.
 * @error: Location to store error information, if any.
 *
 * Reads information for one account from a serialized XML node. The account
 * info can be written to XML with the infd_acl_account_info_to_xml()
 * function. If the function fails it returns %NULL and @error is set.
 *
 * Returns: A #InfdAclAccountInfo, or %NULL. Free with
 * infd_acl_account_info_free() when no longer needed.
 */
InfdAclAccountInfo*
infd_acl_account_info_from_xml(xmlNodePtr xml,
                               GError** error)
{
  InfdAclAccountInfo* info;
  InfAclAccount* account;

  GError* local_error;
  gboolean has_first_seen;
  gdouble first_seen;
  gboolean has_last_seen;
  gdouble last_seen;

  xmlChar* password_salt;
  xmlChar* password_hash;
  gnutls_datum_t datum;
  size_t hash_len;
  int res;
  gchar* binary_salt;
  gchar* binary_hash;

  xmlNodePtr child;
  GPtrArray* certificate_array;
  guint i;

  g_return_val_if_fail(xml != NULL, NULL);
  g_return_val_if_fail(error == NULL || *error == NULL, NULL);

  local_error = NULL;

  has_first_seen = inf_xml_util_get_attribute_double(
    xml,
    "first-seen",
    &first_seen,
    &local_error
  );

  if(local_error != NULL)
    return NULL;

  has_last_seen = inf_xml_util_get_attribute_double(
    xml,
    "last-seen",
    &last_seen,
    &local_error
  );

  if(local_error != NULL)
    return NULL;

  account = inf_acl_account_from_xml(xml, error);
  if(account == NULL) return NULL;

  password_salt = inf_xml_util_get_attribute(xml, "password-salt");
  password_hash = inf_xml_util_get_attribute(xml, "password-hash");

  if( (password_salt != NULL && password_hash == NULL) ||
      (password_salt == NULL && password_hash != NULL))
  {
    g_set_error(
      error,
      inf_request_error_quark(),
      INF_REQUEST_ERROR_INVALID_ATTRIBUTE,
      "%s",
      _("If one of \"password-hash\" or \"password-salt\" is provided, the "
        "other must be provided as well.")
    );

    if(password_salt != NULL) xmlFree(password_salt);
    if(password_hash != NULL) xmlFree(password_hash);

    inf_acl_account_free(account);
    return NULL;
  }

  if(password_salt != NULL && password_hash != NULL)
  {
    datum.data = password_salt;
    datum.size = strlen(password_salt);

    hash_len = 32;
    binary_salt = g_malloc(hash_len);
    res = gnutls_hex_decode(&datum, binary_salt, &hash_len);
    xmlFree(password_salt);

    if(hash_len != 32)
    {
      g_set_error(
        error,
        inf_request_error_quark(),
        INF_REQUEST_ERROR_INVALID_ATTRIBUTE,
        "%s",
        _("The length of the password salt is incorrect, it should "
          "be 32 bytes")
      );

      xmlFree(password_hash);
      g_free(binary_salt);
      return NULL;
    }
    else if(res != GNUTLS_E_SUCCESS)
    {
      inf_gnutls_set_error(error, res);
      xmlFree(password_hash);
      g_free(binary_salt);
      return NULL;
    }

    datum.data = password_hash;
    datum.size = strlen(password_hash);

    hash_len = gnutls_hash_get_len(GNUTLS_DIG_SHA256);
    binary_hash = g_malloc(hash_len);
    res = gnutls_hex_decode(&datum, binary_hash, &hash_len);
    xmlFree(password_hash);
  
    if(hash_len != gnutls_hash_get_len(GNUTLS_DIG_SHA256))
    {
      g_set_error(
        error,
        inf_request_error_quark(),
        INF_REQUEST_ERROR_INVALID_ATTRIBUTE,
        _("The length of the password hash is incorrect, it should be "
          "%u bytes"),
        (unsigned int)gnutls_hash_get_len(GNUTLS_DIG_SHA256)
      );

      g_free(binary_salt);
      g_free(binary_hash);
      return NULL;
    }
    else if(res != GNUTLS_E_SUCCESS)
    {
      inf_gnutls_set_error(error, res);
      g_free(binary_salt);
      g_free(binary_hash);
      return NULL;
    }
  }
  else
  {
    binary_salt = NULL;
    binary_hash = NULL;\

    if(password_salt != NULL) xmlFree(password_salt);
    if(password_hash != NULL) xmlFree(password_hash);
  }

  certificate_array = g_ptr_array_new();
  for(child = xml->children; child != NULL; child = child->next)
  {
    if(child->type != XML_ELEMENT_NODE) continue;
    if(strcmp((const char*)child->name, "certificate") == 0)
      g_ptr_array_add(certificate_array, xmlNodeGetContent(child));
  }

  info = infd_acl_account_info_new(account->id, account->name, FALSE);
  inf_acl_account_free(account);

  info->certificates = g_malloc(sizeof(gchar*) * certificate_array->len);
  for(i = 0; i < certificate_array->len; ++i)
  {
    info->certificates[i] = g_strdup(certificate_array->pdata[i]);
    xmlFree(certificate_array->pdata[i]);
  }
  
  info->n_certificates = certificate_array->len;
  g_ptr_array_free(certificate_array, TRUE);

  info->password_salt = binary_salt;
  info->password_hash = binary_hash;
  if(has_first_seen == TRUE)
    info->first_seen = first_seen * 1e6;
  else
    info->first_seen = 0;

  if(has_last_seen == TRUE)
    info->last_seen = last_seen * 1e6;
  else
    info->last_seen = 0;

  return info;
}
コード例 #15
0
/**
 * infd_acl_account_info_set_password:
 * @info: A #InfdAclAccountInfo.
 * @password: The new password for the account, or %NULL.
 * @error: Location to store error information, if any.
 *
 * Changes the password for the given account. If @password is %NULL the
 * password is unset, which means that it is not possible to log into this
 * account with password authentication.
 *
 * If @password is non-%NULL, a new random salt is generated and a SHA256
 * hash of the salt and the password is stored.
 *
 * If an error occurs while changing the password the functions set @error
 * and returns %FALSE.
 *
 * Returns: %TRUE in case of success or %FALSE otherwise.
 */
gboolean
infd_acl_account_info_set_password(InfdAclAccountInfo* info,
                                   const gchar* password,
                                   GError** error)
{
  gchar* new_salt;
  gchar* new_hash;

  gchar* salted_password;
  guint password_len;
  int res;

  g_return_val_if_fail(info != NULL, FALSE);

  if(password == NULL)
  {
    g_free(info->password_salt);
    g_free(info->password_hash);

    info->password_salt = NULL;
    info->password_hash = NULL;
  }
  else
  {
    new_salt = g_malloc(32);
    res = gnutls_rnd(GNUTLS_RND_RANDOM, new_salt, 32);
    if(res != GNUTLS_E_SUCCESS)
    {
      g_free(new_salt);
      inf_gnutls_set_error(error, res);
      return FALSE;
    }

    password_len = strlen(password);
    salted_password = g_malloc(32 + password_len);

    memcpy(salted_password, new_salt, 16);
    memcpy(salted_password + 16, password, password_len);
    memcpy(salted_password + 16 + password_len, new_salt + 16, 16);

    new_hash = g_malloc(gnutls_hash_get_len(GNUTLS_DIG_SHA256));

    res = gnutls_hash_fast(
      GNUTLS_DIG_SHA256,
      salted_password,
      32 + password_len,
      new_hash
    );

    g_free(salted_password);

    if(res != GNUTLS_E_SUCCESS)
    {
      g_free(new_hash);
      g_free(new_salt);
      inf_gnutls_set_error(error, res);
      return FALSE;
    }

    g_free(info->password_salt);
    g_free(info->password_hash);

    info->password_salt = new_salt;
    info->password_hash = new_hash;
  }

  return TRUE;
}
コード例 #16
0
ファイル: SftpExt.c プロジェクト: Orea1234/mysecureshell
static void DoExtFileHashing_FD(tBuffer *bIn, tBuffer *bOut, u_int32_t id, int fd)
{
	gnutls_digest_algorithm_t gnuTlsAlgo = GNUTLS_DIG_UNKNOWN;
	u_int64_t offset, length;
	u_int32_t blockSize;
	char *algo;
	algo = BufferGetString(bIn);
	offset = BufferGetInt64(bIn);
	length = BufferGetInt64(bIn);
	blockSize = BufferGetInt32(bIn);
	if (lseek(fd, offset, SEEK_SET) == -1)
	{
		SendStatus(bOut, id, errnoToPortable(errno));
		DEBUG((MYLOG_DEBUG, "[DoExtFileHashing_FD]Error lseek1"));
		goto endOfFileHashing;
	}
	if (length == 0)//read the file to the end
	{
		u_int64_t endOfFile;

		if ((endOfFile = lseek(fd, 0, SEEK_END)) == -1)
		{
			SendStatus(bOut, id, errnoToPortable(errno));
			DEBUG((MYLOG_DEBUG, "[DoExtFileHashing_FD]Error lseek2"));
			goto endOfFileHashing;
		}
		length = endOfFile - offset;
		if (lseek(fd, offset, SEEK_SET) == -1)
		{
			SendStatus(bOut, id, errnoToPortable(errno));
			DEBUG((MYLOG_DEBUG, "[DoExtFileHashing_FD]Error lseek3"));
			goto endOfFileHashing;
		}
	}
	if (blockSize == 0)//read length in one time
		blockSize = length;
	DEBUG((MYLOG_DEBUG, "[DoExtFileHashing_FD]Algo:%s Fd:%i Offset:%llu Length:%llu BlockSize:%i",
					algo, fd, offset, length, blockSize));
	if (strcasecmp("md2", algo) == 0)
		gnuTlsAlgo = GNUTLS_DIG_MD2;
	else if (strcasecmp("md5", algo) == 0)
		gnuTlsAlgo = GNUTLS_DIG_MD5;
	else if (strcasecmp("sha1", algo) == 0)
		gnuTlsAlgo = GNUTLS_DIG_SHA1;
	else if (strcasecmp("sha224", algo) == 0)
		gnuTlsAlgo = GNUTLS_DIG_SHA224;
	else if (strcasecmp("sha256", algo) == 0)
		gnuTlsAlgo = GNUTLS_DIG_SHA256;
	else if (strcasecmp("sha384", algo) == 0)
		gnuTlsAlgo = GNUTLS_DIG_SHA384;
	else if (strcasecmp("sha512", algo) == 0)
		gnuTlsAlgo = GNUTLS_DIG_SHA512;
	if (gnuTlsAlgo != GNUTLS_DIG_UNKNOWN)
	{
		gnutls_hash_hd_t dig;
		tBuffer *b;
		size_t keySize = gnutls_hash_get_len(gnuTlsAlgo);
		char *gnuKey;
		char data[SSH2_READ_HASH];
		int inError = 0;
		int gnulTlsError;

		b = BufferNew();
		BufferPutInt8FAST(b, SSH2_FXP_EXTENDED_REPLY);
		BufferPutInt32(b, id);
		BufferPutString(b, algo);
		gnuKey = calloc(1, keySize);
		if (gnuKey == NULL)
			goto endOfFileHashing;
		if ((gnulTlsError = gnutls_hash_init(&dig, gnuTlsAlgo)) == 0)
		{
			while (length > 0)
			{
				u_int32_t r, off, len;

				length = (length > (u_int64_t) blockSize) ? length - (u_int64_t) blockSize : 0;
				off = blockSize;
				len = sizeof(data);
				DEBUG((MYLOG_DEBUG, "[DoExtFileHashing_FD]Read:%i Rest:%llu", len, length));
				while ((r = read(fd, data, len)) > 0)
				{
					DEBUG((MYLOG_DEBUG, "[DoExtFileHashing_FD]Compute block (%u/%u %u)", len, r, off));
					if ((gnulTlsError = gnutls_hash(dig, data, r)) != 0)
					{
						DEBUG((MYLOG_DEBUG, "[DoExtFileHashing_FD]Error gnutls_hmac [error: %i]", gnulTlsError));
						inError = 1;
						break;
					}
					off -= r;
					if (off < sizeof(data))
						len = off;
					if (off == 0)
						break;
				}
			}
		}
		else
		{
			DEBUG((MYLOG_DEBUG, "[DoExtFileHashing_FD]Error gnutls_hash_init [keySize: %li] [error: %i]", keySize, gnulTlsError));
			inError = 1;
		}
		if (inError == 0)
		{
			DEBUG((MYLOG_DEBUG, "[DoExtFileHashing_FD]Compute key... [keySize: %li][keyPointer: %p]", keySize, gnuKey));
			gnutls_hash_deinit(dig, gnuKey);
			DEBUG((MYLOG_DEBUG, "[DoExtFileHashing_FD]Hash: %X%X%X ...", gnuKey[0], gnuKey[1], gnuKey[2]));
			BufferPutRawData(b, gnuKey, keySize);
			BufferPutPacket(bOut, b);
		}
		else
			SendStatus(bOut, id, SSH2_FX_FAILURE);
		BufferDelete(b);
		free(gnuKey);
	}
	else
	{
		DEBUG((MYLOG_DEBUG, "[DoExtFileHashing_FD]No algorithm: %s", algo));
		SendStatus(bOut, id, SSH2_FX_OP_UNSUPPORTED);
	}
	endOfFileHashing: DEBUG((MYLOG_DEBUG, "[DoExtFileHashing_FD]End"));
	free(algo);
}
コード例 #17
0
gboolean
crypto_md5_hash (const char *salt,
                 const gsize salt_len,
                 const char *password,
                 gsize password_len,
                 char *buffer,
                 gsize buflen,
                 GError **error)
{
	gnutls_hash_hd_t ctx;
	int err;
	int nkey = buflen;
	const gsize digest_len = 16;
	int count = 0;
	char digest[MD5_HASH_LEN];
	char *p = buffer;

	if (salt)
		g_return_val_if_fail (salt_len >= SALT_LEN, FALSE);

	g_return_val_if_fail (password != NULL, FALSE);
	g_return_val_if_fail (password_len > 0, FALSE);
	g_return_val_if_fail (buffer != NULL, FALSE);
	g_return_val_if_fail (buflen > 0, FALSE);

	if (gnutls_hash_get_len (GNUTLS_DIG_MD5) > MD5_HASH_LEN) {
		g_set_error (error, NM_CRYPTO_ERROR,
		             NM_CRYPTO_ERR_MD5_INIT_FAILED,
		             _("Hash length too long (%d > %d)."),
		             gnutls_hash_get_len (GNUTLS_DIG_MD5), MD5_HASH_LEN);
		return FALSE;
	}

	while (nkey > 0) {
		int i = 0;

		err = gnutls_hash_init (&ctx, GNUTLS_DIG_MD5);
		if (err < 0)
			goto error;

		if (count++)
			gnutls_hash (ctx, digest, digest_len);
		gnutls_hash (ctx, password, password_len);
		if (salt)
			gnutls_hash (ctx, salt, SALT_LEN); /* Only use 8 bytes of salt */
		gnutls_hash_deinit (ctx, digest);

		while (nkey && (i < digest_len)) {
			*(p++) = digest[i++];
			nkey--;
		}
	}

	memset (digest, 0, sizeof (digest));
	return TRUE;
error:
	memset (digest, 0, sizeof (digest));
	g_set_error (error, NM_CRYPTO_ERROR,
	             NM_CRYPTO_ERR_MD5_INIT_FAILED,
	             _("Failed to initialize the MD5 engine: %s (%s)"),
	             gnutls_strerror_name (err), gnutls_strerror (err));
	return FALSE;
}