Exemplo n.º 1
0
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;
}
Exemplo n.º 2
0
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;
}
Exemplo n.º 3
0
static void http_head(http_t *http, const char *field, const char *value)
{
	static char hash[20] = {};
	static char extra[]  = "258EAFA5-E914-47DA-95CA-C5AB0DC85B11";

	trace("    http_head: %-20s -> [%s]", field, value);
	if (!strcasecmp(field, "Upgrade")) {
		http->hdr_upgrade = !!strcasestr(value, "websocket");
	}
	else if (!strcasecmp(field, "Connection")) {
		http->hdr_connect = !!strcasestr(value, "upgrade");
	}
	else if (!strcasecmp(field, "Sec-WebSocket-Key")) {
#ifdef USE_GNUTLS
		gnutls_hash_hd_t sha1;
		gnutls_hash_init(&sha1, GNUTLS_DIG_SHA1);
		gnutls_hash(sha1, value, strlen(value));
		gnutls_hash(sha1, extra, strlen(extra));
		gnutls_hash_output(sha1, hash);
#endif
#ifdef USE_OPENSSL
		SHA_CTX sha1;
		SHA1_Init(&sha1);
		SHA1_Update(&sha1, value, strlen(value));
		SHA1_Update(&sha1, extra, strlen(extra));
		SHA1_Final((unsigned char*)hash, &sha1);
#endif
		http->hdr_accept = base64(hash, sizeof(hash),
			http->hdr_key, sizeof(http->hdr_key));
	}
}
Exemplo n.º 4
0
		// Nothing to deallocate, constructor may throw freely
		Hash(const std::string& hashname)
		{
			// As older versions of gnutls can't do this, let's disable it where needed.
#ifdef GNUTLS_HAS_MAC_GET_ID
			// As gnutls_digest_algorithm_t and gnutls_mac_algorithm_t are mapped 1:1, we can do this
			// There is no gnutls_dig_get_id() at the moment, but it may come later
			hash = (gnutls_digest_algorithm_t)gnutls_mac_get_id(hashname.c_str());
			if (hash == GNUTLS_DIG_UNKNOWN)
				throw Exception("Unknown hash type " + hashname);

			// Check if the user is giving us something that is a valid MAC but not digest
			gnutls_hash_hd_t is_digest;
			if (gnutls_hash_init(&is_digest, hash) < 0)
				throw Exception("Unknown hash type " + hashname);
			gnutls_hash_deinit(is_digest, NULL);
#else
			if (hashname == "md5")
				hash = GNUTLS_DIG_MD5;
			else if (hashname == "sha1")
				hash = GNUTLS_DIG_SHA1;
#ifdef INSPIRCD_GNUTLS_ENABLE_SHA256_FINGERPRINT
			else if (hashname == "sha256")
				hash = GNUTLS_DIG_SHA256;
#endif
			else
				throw Exception("Unknown hash type " + hashname);
#endif
		}
Exemplo n.º 5
0
CryptoMd5
crypto_md5_init(void)
{
	CryptoMd5 md5 = xmalloc(sizeof(*md5));
	int x = gnutls_hash_init(&md5->dig, GNUTLS_DIG_MD5);
	ASSERT(!x);
	return md5;
}
Exemplo n.º 6
0
CryptoSha1
crypto_sha1_init(void)
{
	CryptoSha1 sha1 = xmalloc(sizeof(*sha1));
	int x = gnutls_hash_init(&sha1->dig, GNUTLS_DIG_SHA1);
	ASSERT(!x);
	return sha1;
}
Exemplo n.º 7
0
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);
}
Exemplo n.º 8
0
void Digest::reset(void)
{
    unsigned char temp[MAX_DIGEST_HASHSIZE / 8];

    if(context) {
        gnutls_hash_deinit((MD_CTX)context, temp);
        context = NULL;
    }
    if(hashid == 0)
        return;

    gnutls_hash_init((MD_CTX *)&context, (MD_ID)hashid);
    bufsize = 0;
}
Exemplo n.º 9
0
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);
}
Exemplo n.º 10
0
std::unique_ptr<CryptoDigest> CryptoDigest::create(CryptoAlgorithmIdentifier algorithm)
{
    gnutls_digest_algorithm_t gnutlsAlgorithm;

    switch (algorithm) {
    case CryptoAlgorithmIdentifier::SHA_1: {
        gnutlsAlgorithm = GNUTLS_DIG_SHA1;
        break;
    }
    case CryptoAlgorithmIdentifier::SHA_224: {
        gnutlsAlgorithm = GNUTLS_DIG_SHA224;
        break;
    }
    case CryptoAlgorithmIdentifier::SHA_256: {
        gnutlsAlgorithm = GNUTLS_DIG_SHA256;
        break;
    }
    case CryptoAlgorithmIdentifier::SHA_384: {
        gnutlsAlgorithm = GNUTLS_DIG_SHA384;
        break;
    }
    case CryptoAlgorithmIdentifier::SHA_512: {
        gnutlsAlgorithm = GNUTLS_DIG_SHA512;
        break;
    }
    default:
        return nullptr;
    }

    std::unique_ptr<CryptoDigest> digest(new CryptoDigest);
    digest->m_context->algorithm = gnutlsAlgorithm;

    int ret = gnutls_hash_init(&digest->m_context->hash, gnutlsAlgorithm);
    if (ret != GNUTLS_E_SUCCESS)
        return nullptr;

    return digest;
}
Exemplo n.º 11
0
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);
}
Exemplo n.º 12
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;
}