Ejemplo n.º 1
0
/* [RFC 3414] - A.2. Password to Key Algorithm */
enum snmp_code
snmp_passwd_to_keys(struct snmp_user *user, char *passwd)
{
	int err, loop, i, pwdlen;
	uint32_t  keylen, olen;
	const EVP_MD *dtype;
	EVP_MD_CTX ctx;
	uint8_t authbuf[SNMP_AUTH_BUF_SIZE];

	if (passwd == NULL || user == NULL)
		return (SNMP_CODE_FAILED);

	err = snmp_digest_init(user, &ctx, &dtype, &keylen);
	if (err < 0)
		return (SNMP_CODE_BADDIGEST);
	else if (err == 0)
		return (SNMP_CODE_OK);

	memset(user->auth_key, 0, sizeof(user->auth_key));
	pwdlen = strlen(passwd);

	for (loop = 0; loop < SNMP_AUTH_KEY_LOOPCNT; loop += i) {
		for (i = 0; i < SNMP_EXTENDED_KEY_SIZ; i++)
			authbuf[i] = passwd[(loop + i) % pwdlen];
		if (EVP_DigestUpdate(&ctx, authbuf, SNMP_EXTENDED_KEY_SIZ) != 1)
			goto failed;
	}

	if (EVP_DigestFinal(&ctx, user->auth_key, &olen) != 1)
		goto failed;

	EVP_MD_CTX_cleanup(&ctx);
	return (SNMP_CODE_OK);

failed:
	EVP_MD_CTX_cleanup(&ctx);
	return (SNMP_CODE_BADDIGEST);
}
Ejemplo n.º 2
0
/* [RFC 3414] - 2.6. Key Localization Algorithm */
enum snmp_code
snmp_get_local_keys(struct snmp_user *user, uint8_t *eid, uint32_t elen)
{
	int err;
	uint32_t  keylen, olen;
	const EVP_MD *dtype;
	EVP_MD_CTX ctx;
	uint8_t authbuf[SNMP_AUTH_BUF_SIZE];

	if (user == NULL || eid == NULL || elen > SNMP_ENGINE_ID_SIZ)
		return (SNMP_CODE_FAILED);

	memset(user->priv_key, 0, sizeof(user->priv_key));
	memset(authbuf, 0, sizeof(authbuf));

	err = snmp_digest_init(user, &ctx, &dtype, &keylen);
	if (err < 0)
		return (SNMP_CODE_BADDIGEST);
	else if (err == 0)
		return (SNMP_CODE_OK);

	memcpy(authbuf, user->auth_key, keylen);
	memcpy(authbuf + keylen, eid, elen);
	memcpy(authbuf + keylen + elen, user->auth_key, keylen);

	if (EVP_DigestUpdate(&ctx, authbuf, 2 * keylen + elen) != 1 ||
	    EVP_DigestFinal(&ctx, user->auth_key, &olen) != 1) {
		EVP_MD_CTX_cleanup(&ctx);
		return (SNMP_CODE_BADDIGEST);
	}
	EVP_MD_CTX_cleanup(&ctx);

	if (user->priv_proto != SNMP_PRIV_NOPRIV)
		memcpy(user->priv_key, user->auth_key, sizeof(user->priv_key));

	return (SNMP_CODE_OK);
}
Ejemplo n.º 3
0
/*
 * hash a byte sequence with the specified algorithm
 */
apr_byte_t oidc_jose_hash_bytes(apr_pool_t *pool, const char *s_digest,
		const unsigned char *input, unsigned int input_len,
		unsigned char **output, unsigned int *output_len,
		oidc_jose_error_t *err) {
	unsigned char md_value[EVP_MAX_MD_SIZE];

	EVP_MD_CTX *ctx = EVP_MD_CTX_new();
	EVP_MD_CTX_init(ctx);

	const EVP_MD *evp_digest = NULL;
	if ((evp_digest = EVP_get_digestbyname(s_digest)) == NULL) {
		oidc_jose_error(err,
				"no OpenSSL digest algorithm found for algorithm \"%s\"",
				s_digest);
		return FALSE;
	}

	if (!EVP_DigestInit_ex(ctx, evp_digest, NULL)) {
		oidc_jose_error_openssl(err, "EVP_DigestInit_ex");
		return FALSE;
	}
	if (!EVP_DigestUpdate(ctx, input, input_len)) {
		oidc_jose_error_openssl(err, "EVP_DigestUpdate");
		return FALSE;
	}
	if (!EVP_DigestFinal(ctx, md_value, output_len)) {
		oidc_jose_error_openssl(err, "EVP_DigestFinal");
		return FALSE;
	}

	EVP_MD_CTX_free(ctx);

	*output = apr_pcalloc(pool, *output_len);
	memcpy(*output, md_value, *output_len);

	return TRUE;
}
Ejemplo n.º 4
0
//Copied from aegis-crypto0 bin/accli.c
int PackageUtils::computeDigest(int ih, unsigned char* digest, ssize_t maxdigestlen)
{
    EVP_MD_CTX mdctx;
    unsigned int mdlen;
    unsigned char data[512];
    int rc;
    ssize_t len;

    if (maxdigestlen < DIGESTLEN)
        return(-EINVAL);

    rc = EVP_DigestInit(&mdctx, DIGESTTYP());
    if (EVPOK != rc) {
        qDebug()<<"EVP_DigestInit returns "<< rc;
        return 0;
    }

    while (0 < (len = read(ih, data, sizeof(data)))) {
        rc = EVP_DigestUpdate(&mdctx, data, len);
        if (EVPOK != rc) {
            qDebug()<<"EVP_DigestUpdate returns:"<<rc<<Q_FUNC_INFO;
            return 0;
        }
        if (len < sizeof(data))
           break;
    }

    rc = EVP_DigestFinal(&mdctx, digest, &mdlen);
    if (rc != EVPOK) {
        qDebug()<<"EVP_DigestUpdate returns:"<<rc<<Q_FUNC_INFO;
        return(0);
    }

    EVP_MD_CTX_cleanup(&mdctx);

    return mdlen;
}
Ejemplo n.º 5
0
/*
 * Not really public interface,
 * but common routine called from both client and server.
 */
int
gfs_digest_calculate_local(int fd, char *buffer, size_t buffer_size,
	const EVP_MD *md_type, EVP_MD_CTX *md_ctx,
	size_t *md_lenp, unsigned char *md_value,
	file_offset_t *filesizep)
{
	int size;
	file_offset_t off = 0;
	unsigned int len;

	if (lseek(fd, (off_t)0, 0) == -1)
		return (errno);

	EVP_DigestInit(md_ctx, md_type);
	while ((size = read(fd, buffer, buffer_size)) > 0) {
		EVP_DigestUpdate(md_ctx, buffer, size);
		off += size;
	}
	EVP_DigestFinal(md_ctx, md_value, &len);

	*md_lenp = len;
	*filesizep = off;
	return (size == -1 ? errno : 0);
}
Ejemplo n.º 6
0
static PyObject *
EVP_hexdigest(EVPobject *self, PyObject *unused)
{
    unsigned char digest[EVP_MAX_MD_SIZE];
    EVP_MD_CTX *temp_ctx;
    unsigned int digest_size;

    temp_ctx = EVP_MD_CTX_new();
    if (temp_ctx == NULL) {
        PyErr_NoMemory();
        return NULL;
    }

    /* Get the raw (binary) digest value */
    if (!locked_EVP_MD_CTX_copy(temp_ctx, self)) {
        return _setException(PyExc_ValueError);
    }
    digest_size = EVP_MD_CTX_size(temp_ctx);
    EVP_DigestFinal(temp_ctx, digest, NULL);

    EVP_MD_CTX_free(temp_ctx);

    return _Py_strhex((const char *)digest, digest_size);
}
Ejemplo n.º 7
0
/*
 * Not really public interface,
 * but common routine called from both client and server.
 */
int
gfs_digest_calculate_local(int fd, char *buffer, size_t buffer_size,
	const EVP_MD *md_type, EVP_MD_CTX *md_ctx,
	size_t *md_lenp, unsigned char *md_value,
	gfarm_off_t *filesizep)
{
	int size, save_errno;
	gfarm_off_t off = 0;
	unsigned int len;

	if (lseek(fd, (off_t)0, 0) == -1) {
		save_errno = errno;
		gflog_debug(GFARM_MSG_1001020, "lseek() failed: %s",
			strerror(save_errno));
		return (save_errno);
	}

	EVP_DigestInit(md_ctx, md_type);
	while ((size = read(fd, buffer, buffer_size)) > 0) {
		EVP_DigestUpdate(md_ctx, buffer, size);
		off += size;
	}
	EVP_DigestFinal(md_ctx, md_value, &len);

	*md_lenp = len;
	*filesizep = off;

	if (size == -1) {
		save_errno = errno;
		gflog_debug(GFARM_MSG_1001021, "read() failed: %s",
			strerror(save_errno));
		return (save_errno);
	}

	return (0);
}
Ejemplo n.º 8
0
static PyObject *
EVP_digest(EVPobject *self, PyObject *unused)
{
    unsigned char digest[EVP_MAX_MD_SIZE];
    EVP_MD_CTX *temp_ctx;
    PyObject *retval;
    unsigned int digest_size;

    temp_ctx = EVP_MD_CTX_new();
    if (temp_ctx == NULL) {
        PyErr_NoMemory();
        return NULL;
    }

    if (!locked_EVP_MD_CTX_copy(temp_ctx, self)) {
        return _setException(PyExc_ValueError);
    }
    digest_size = EVP_MD_CTX_size(temp_ctx);
    EVP_DigestFinal(temp_ctx, digest, NULL);

    retval = PyBytes_FromStringAndSize((const char *)digest, digest_size);
    EVP_MD_CTX_free(temp_ctx);
    return retval;
}
Ejemplo n.º 9
0
static void sl_digest (void){
  SLang_BString_Type* data; /* we will give a slang string */
  unsigned char output[EVP_MAX_MD_SIZE];
  const EVP_MD *md;
  EVP_MD_CTX ctx;
  char* dtype;
  int dlen, hashlen;
  SLang_BString_Type *out;
  
  if (SLang_Num_Function_Args != 2 ||
      SLang_pop_slstring(&dtype) == -1 ){
    return;}

  md = EVP_get_digestbyname(dtype);
  if (!md){
    SLang_verror(SL_UNDEFINED_NAME,"could not find digest %s",dtype);
    SLang_free_slstring(dtype);
    return;
  }
  
  if (SLang_pop_bstring(&data) == -1 ){
    return;
  }

  unsigned char* idata = SLbstring_get_pointer (data,&dlen);

  EVP_MD_CTX_init(&ctx);
  EVP_DigestInit_ex(&ctx, md, NULL);
  EVP_DigestUpdate(&ctx, idata, dlen);
  EVP_DigestFinal(&ctx, output, &hashlen);

  out = SLbstring_create (output, hashlen);
  SLang_push_bstring(out);
  SLbstring_free(data);
  SLbstring_free(out);
}
Ejemplo n.º 10
0
int ssh_dss_verify(DSA *key,
                   u_char *signature, u_int signaturelen,
                   u_char *data, u_int datalen)
{
	DSA_SIG *sig;
	const EVP_MD *evp_md = EVP_sha1();
	EVP_MD_CTX md;
	unsigned char digest[EVP_MAX_MD_SIZE], *sigblob;
	unsigned int len, dlen;
	int ret;
	char *ptr;

	OpenSSL_add_all_digests();

	if (key == NULL) {
		return -2;
	}

	ptr = signature;

	// step1
	if (signaturelen == 0x28) {
		// workaround for SSH-2.0-2.0* and SSH-2.0-2.1* (2006.11.18 maya)
		ptr -= 4;
	}
	else {
		len = get_uint32_MSBfirst(ptr);
		ptr += 4;
		if (strncmp("ssh-dss", ptr, len) != 0) {
			return -3;
		}
		ptr += len;
	}

	// step2
	len = get_uint32_MSBfirst(ptr);
	ptr += 4;
	sigblob = ptr;
	ptr += len;

	if (len != SIGBLOB_LEN) {
		return -4;
	}

	/* parse signature */
	if ((sig = DSA_SIG_new()) == NULL)
		return -5;
	if ((sig->r = BN_new()) == NULL)
		return -6;
	if ((sig->s = BN_new()) == NULL)
		return -7;
	BN_bin2bn(sigblob, INTBLOB_LEN, sig->r);
	BN_bin2bn(sigblob+ INTBLOB_LEN, INTBLOB_LEN, sig->s);

	/* sha1 the data */
	EVP_DigestInit(&md, evp_md);
	EVP_DigestUpdate(&md, data, datalen);
	EVP_DigestFinal(&md, digest, &dlen);

	ret = DSA_do_verify(digest, dlen, sig, key);
	memset(digest, 'd', sizeof(digest));

	DSA_SIG_free(sig);

	return ret;
}
Ejemplo n.º 11
0
int ssh_ecdsa_verify(EC_KEY *key, ssh_keytype keytype,
                     u_char *signature, u_int signaturelen,
                     u_char *data, u_int datalen)
{
	ECDSA_SIG *sig;
	const EVP_MD *evp_md;
	EVP_MD_CTX md;
	unsigned char digest[EVP_MAX_MD_SIZE], *sigblob;
	unsigned int len, dlen;
	int ret, nid = NID_undef;
	char *ptr;

	OpenSSL_add_all_digests();

	if (key == NULL) {
		return -2;
	}

	ptr = signature;

	len = get_uint32_MSBfirst(ptr);
	ptr += 4;
	if (strncmp(get_ssh_keytype_name(keytype), ptr, len) != 0) {
		return -3;
	}
	ptr += len;

	len = get_uint32_MSBfirst(ptr);
	ptr += 4;
	sigblob = ptr;
	ptr += len;

	/* parse signature */
	if ((sig = ECDSA_SIG_new()) == NULL)
		return -4;
	if ((sig->r = BN_new()) == NULL)
		return -5;
	if ((sig->s = BN_new()) == NULL)
		return -6;

	buffer_get_bignum2(&sigblob, sig->r);
	buffer_get_bignum2(&sigblob, sig->s);
	if (sigblob != ptr) {
		return -7;
	}

	/* hash the data */
	nid = keytype_to_hash_nid(keytype);
	if ((evp_md = EVP_get_digestbynid(nid)) == NULL) {
		return -8;
	}
	EVP_DigestInit(&md, evp_md);
	EVP_DigestUpdate(&md, data, datalen);
	EVP_DigestFinal(&md, digest, &dlen);

	ret = ECDSA_do_verify(digest, dlen, sig, key);
	memset(digest, 'd', sizeof(digest));

	ECDSA_SIG_free(sig);

	return ret;
}
Ejemplo n.º 12
0
int ssh_rsa_verify(RSA *key,
                   u_char *signature, u_int signaturelen,
                   u_char *data, u_int datalen)
{
	const EVP_MD *evp_md;
	EVP_MD_CTX md;
	//	char *ktype;
	u_char digest[EVP_MAX_MD_SIZE], *sigblob;
	u_int len, dlen, modlen;
//	int rlen, ret, nid;
	int ret, nid;
	char *ptr;

	OpenSSL_add_all_digests();

	if (key == NULL) {
		return -2;
	}
	if (BN_num_bits(key->n) < SSH_RSA_MINIMUM_MODULUS_SIZE) {
		return -3;
	}
	//debug_print(41, signature, signaturelen);
	ptr = signature;

	// step1
	len = get_uint32_MSBfirst(ptr);
	ptr += 4;
	if (strncmp("ssh-rsa", ptr, len) != 0) {
		return -4;
	}
	ptr += len;

	// step2
	len = get_uint32_MSBfirst(ptr);
	ptr += 4;
	sigblob = ptr;
	ptr += len;
#if 0
	rlen = get_uint32_MSBfirst(ptr);
	if (rlen != 0) {
		return -1;
	}
#endif

	/* RSA_verify expects a signature of RSA_size */
	modlen = RSA_size(key);
	if (len > modlen) {
		return -5;

	} else if (len < modlen) {
		u_int diff = modlen - len;
		sigblob = realloc(sigblob, modlen);
		memmove(sigblob + diff, sigblob, len);
		memset(sigblob, 0, diff);
		len = modlen;
	}
	
	/* sha1 the data */
	//	nid = (datafellows & SSH_BUG_RSASIGMD5) ? NID_md5 : NID_sha1;
	nid = NID_sha1;
	if ((evp_md = EVP_get_digestbynid(nid)) == NULL) {
		//error("ssh_rsa_verify: EVP_get_digestbynid %d failed", nid);
		return -6;
	}
	EVP_DigestInit(&md, evp_md);
	EVP_DigestUpdate(&md, data, datalen);
	EVP_DigestFinal(&md, digest, &dlen);

	ret = openssh_RSA_verify(nid, digest, dlen, sigblob, len, key);

	memset(digest, 'd', sizeof(digest));
	memset(sigblob, 's', len);
	//free(sigblob);
	//debug("ssh_rsa_verify: signature %scorrect", (ret==0) ? "in" : "");

	return ret;
}
Ejemplo n.º 13
0
BOOL generate_SSH2_keysign(Key *keypair, char **sigptr, int *siglen, char *data, int datalen)
{
	buffer_t *msg = NULL;
	char *s;
	int ret;

	msg = buffer_init();
	if (msg == NULL) {
		// TODO: error check
		return FALSE;
	}

	switch (keypair->type) {
	case KEY_RSA: // RSA
	{
		const EVP_MD *evp_md = EVP_sha1();
		EVP_MD_CTX md;
		u_char digest[EVP_MAX_MD_SIZE], *sig;
		u_int slen, dlen, len;
		int ok, nid = NID_sha1;

		// ダイジェスト値の計算
		EVP_DigestInit(&md, evp_md);
		EVP_DigestUpdate(&md, data, datalen);
		EVP_DigestFinal(&md, digest, &dlen);

		slen = RSA_size(keypair->rsa);
		sig = malloc(slen);
		if (sig == NULL)
			goto error;

		// 電子署名を計算
		ok = RSA_sign(nid, digest, dlen, sig, &len, keypair->rsa);
		memset(digest, 'd', sizeof(digest));
		if (ok != 1) { // error
			free(sig);
			goto error;
		}
		// 署名のサイズがバッファより小さい場合、後ろへずらす。先頭はゼロで埋める。
		if (len < slen) {
			u_int diff = slen - len;
			memmove(sig + diff, sig, len);
			memset(sig, 0, diff);

		} else if (len > slen) {
			free(sig);
			goto error;

		} else {
			// do nothing

		}

		s = get_sshname_from_key(keypair);
		buffer_put_string(msg, s, strlen(s));
		buffer_append_length(msg, sig, slen);
		len = buffer_len(msg);

		// setting
		*siglen = len;
		*sigptr = malloc(len);
		if (*sigptr == NULL) {
			free(sig);
			goto error;
		}
		memcpy(*sigptr, buffer_ptr(msg), len);
		free(sig);
		
		break;
	}
	case KEY_DSA: // DSA
	{
		DSA_SIG *sig;
		const EVP_MD *evp_md = EVP_sha1();
		EVP_MD_CTX md;
		u_char digest[EVP_MAX_MD_SIZE], sigblob[SIGBLOB_LEN];
		u_int rlen, slen, len, dlen;

		// ダイジェストの計算
		EVP_DigestInit(&md, evp_md);
		EVP_DigestUpdate(&md, data, datalen);
		EVP_DigestFinal(&md, digest, &dlen);

		// DSA電子署名を計算
		sig = DSA_do_sign(digest, dlen, keypair->dsa);
		memset(digest, 'd', sizeof(digest));
		if (sig == NULL) {
			goto error;
		}

		// BIGNUMからバイナリ値への変換
		rlen = BN_num_bytes(sig->r);
		slen = BN_num_bytes(sig->s);
		if (rlen > INTBLOB_LEN || slen > INTBLOB_LEN) {
			DSA_SIG_free(sig);
			goto error;
		}
		memset(sigblob, 0, SIGBLOB_LEN);
		BN_bn2bin(sig->r, sigblob+ SIGBLOB_LEN - INTBLOB_LEN - rlen);
		BN_bn2bin(sig->s, sigblob+ SIGBLOB_LEN - slen);
		DSA_SIG_free(sig);

		// setting
		s = get_sshname_from_key(keypair);
		buffer_put_string(msg, s, strlen(s));
		buffer_append_length(msg, sigblob, sizeof(sigblob));
		len = buffer_len(msg);

		// setting
		*siglen = len;
		*sigptr = malloc(len);
		if (*sigptr == NULL) {
			goto error;
		}
		memcpy(*sigptr, buffer_ptr(msg), len);

		break;
	}
	case KEY_ECDSA256: // ECDSA
	case KEY_ECDSA384:
	case KEY_ECDSA521:
	{
		ECDSA_SIG *sig;
		const EVP_MD *evp_md;
		EVP_MD_CTX md;
		u_char digest[EVP_MAX_MD_SIZE];
		u_int len, dlen, nid;
		buffer_t *buf2 = NULL;

		nid = keytype_to_hash_nid(keypair->type);
		if ((evp_md = EVP_get_digestbynid(nid)) == NULL) {
			goto error;
		}
		EVP_DigestInit(&md, evp_md);
		EVP_DigestUpdate(&md, data, datalen);
		EVP_DigestFinal(&md, digest, &dlen);

		sig = ECDSA_do_sign(digest, dlen, keypair->ecdsa);
		memset(digest, 'd', sizeof(digest));

		if (sig == NULL) {
			goto error;
		}

		buf2 = buffer_init();
		if (buf2 == NULL) {
			// TODO: error check
			goto error;
		}
		buffer_put_bignum2(buf2, sig->r);
		buffer_put_bignum2(buf2, sig->s);
		ECDSA_SIG_free(sig);

		s = get_sshname_from_key(keypair);
		buffer_put_string(msg, s, strlen(s));
		buffer_put_string(msg, buffer_ptr(buf2), buffer_len(buf2));
		buffer_free(buf2);
		len = buffer_len(msg);

		*siglen = len;
		*sigptr = malloc(len);
		if (*sigptr == NULL) {
			goto error;
		}
		memcpy(*sigptr, buffer_ptr(msg), len);

		break;
	}

	case KEY_ED25519:
		ret = ssh_ed25519_sign(keypair, sigptr, siglen, data, datalen);
		if (ret != 0) 
			goto error;
		break;

	default:
		buffer_free(msg);
		return FALSE;
		break;
	}

	buffer_free(msg);
	return TRUE;

error:
	buffer_free(msg);

	return FALSE;
}
Ejemplo n.º 14
0
char *
lcg_compute_checksum (const char *file, enum gfal_cksm_type cksmtype, char *errbuf, int errbufsz)
{
	unsigned long cksm = 0;
	EVP_MD_CTX evpctx;
	int fd = -1;
	unsigned int nbread = 0;
	char buffer[GFAL_CKSM_BUFSIZE];
	char checksum[2 * EVP_MAX_MD_SIZE + 1];
	unsigned char cksm_raw[EVP_MAX_MD_SIZE + 1];
	int cksmsize = 0;

	if (file == NULL || cksmtype == GFAL_CKSM_NONE) {
		gfal_errmsg (errbuf, errbufsz, GFAL_ERRLEVEL_ERROR, "[LCG-UTIL][compute_checksum][] Invalid arguments");
		errno = EINVAL;
		return (NULL);
	}

	memset (checksum, 0, (2 * EVP_MAX_MD_SIZE + 1) * sizeof (char));

	if (cksmtype == GFAL_CKSM_CRC32 || cksmtype == GFAL_CKSM_ADLER32) {
		zlib_handle = dlopen ("libz.so", RTLD_LAZY);
		if (zlib_handle == NULL) {
			gfal_errmsg (errbuf, errbufsz, GFAL_ERRLEVEL_ERROR, "[LCG-UTIL][compute_checksum][] CRC32/ADLER32 need zlib!");
			errno = ELIBACC;
			return (NULL);
		}

		zlib_crc32 = (unsigned long (*) (unsigned long, const char *, unsigned int)) dlsym (zlib_handle, "crc32");
		zlib_adler32 = (unsigned long (*) (unsigned long, const char *, unsigned int)) dlsym (zlib_handle, "adler32");
		if (zlib_crc32 == NULL || zlib_adler32 == NULL) {
			gfal_errmsg (errbuf, errbufsz, GFAL_ERRLEVEL_ERROR, "[LCG-UTIL][compute_checksum][] invalid zlib library!");
			errno = ELIBBAD;
			return (NULL);
		}
	}

	fd = gfal_open (file, O_RDONLY, 0);
	if (fd < 0)
		return (NULL);

	if (cksmtype == GFAL_CKSM_ADLER32)
		cksm = zlib_adler32 (0L, 0, 0);
	else if (cksmtype == GFAL_CKSM_CRC32)
		cksm = zlib_crc32 (0L, 0, 0);
	else {
		if (cksmtype == GFAL_CKSM_MD5)
			EVP_DigestInit (&evpctx, EVP_md5());
		else
			EVP_DigestInit (&evpctx, EVP_sha1());
	}

	while ((nbread = (unsigned int) gfal_read (fd, buffer, GFAL_CKSM_BUFSIZE)) > 0) {
		if (cksmtype == GFAL_CKSM_ADLER32)
			cksm = zlib_adler32 (cksm, buffer, nbread);
		else if (cksmtype == GFAL_CKSM_CRC32)
			cksm = zlib_crc32 (cksm, buffer, nbread);
		else
			EVP_DigestUpdate(&evpctx, buffer, (size_t) nbread);
	}

	gfal_close (fd);

	if (nbread < 0)
		return (NULL);

	if (cksmtype == GFAL_CKSM_ADLER32 || cksmtype == GFAL_CKSM_CRC32) {
		sprintf(checksum, "%08x", (unsigned int) cksm);
	} else {
		char *p;
		int i;

		EVP_DigestFinal (&evpctx, cksm_raw, &cksmsize);

		for (i = 0, p = checksum; i < cksmsize; ++i, p = p + 2)
			sprintf(p, "%02x", cksm_raw[i]);
	}

	return (strdup (checksum));
}
Ejemplo n.º 15
0
static int
EVP_DigestFinal_ex(EVP_MD_CTX *ctx, unsigned char *res, unsigned int *len)
{
	EVP_DigestFinal(ctx, res, len);
	return 1;
}
Ejemplo n.º 16
0
int RSA_padding_add_PKCS1_PSS(RSA *rsa, unsigned char *EM,
      const unsigned char *mHash,
      const EVP_MD *Hash, int sLen)
  {
  int i;
  int ret = 0;
  int hLen, maskedDBLen, MSBits, emLen;
  unsigned char *H, *salt = NULL, *p;
  EVP_MD_CTX ctx;

  hLen = EVP_MD_size(Hash);
  /*
   * Negative sLen has special meanings:
   *  -1  sLen == hLen
   *  -2  salt length is maximized
   *  -N  reserved
   */
  if      (sLen == -1)  sLen = hLen;
  else if (sLen == -2)  sLen = -2;
  else if (sLen < -2)
    {
    RSAerr(RSA_F_RSA_PADDING_ADD_PKCS1_PSS, RSA_R_SLEN_CHECK_FAILED);
    goto err;
    }

  MSBits = (BN_num_bits(rsa->n) - 1) & 0x7;
  emLen = RSA_size(rsa);
  if (MSBits == 0)
    {
    *EM++ = 0;
    emLen--;
    }
  if (sLen == -2)
    {
    sLen = emLen - hLen - 2;
    }
  else if (emLen < (hLen + sLen + 2))
    {
    RSAerr(RSA_F_RSA_PADDING_ADD_PKCS1_PSS,
       RSA_R_DATA_TOO_LARGE_FOR_KEY_SIZE);
    goto err;
    }
  if (sLen > 0)
    {
    salt = OPENSSL_malloc(sLen);
    if (!salt)
      {
      RSAerr(RSA_F_RSA_PADDING_ADD_PKCS1_PSS,
           ERR_R_MALLOC_FAILURE);
      goto err;
      }
    if (!RAND_bytes(salt, sLen))
      goto err;
    }
  maskedDBLen = emLen - hLen - 1;
  H = EM + maskedDBLen;
  EVP_MD_CTX_init(&ctx);
  EVP_DigestInit_ex(&ctx, Hash, NULL);
  EVP_DigestUpdate(&ctx, zeroes, sizeof zeroes);
  EVP_DigestUpdate(&ctx, mHash, hLen);
  if (sLen)
    EVP_DigestUpdate(&ctx, salt, sLen);
  EVP_DigestFinal(&ctx, H, NULL);
  EVP_MD_CTX_cleanup(&ctx);

  /* Generate dbMask in place then perform XOR on it */
  PKCS1_MGF1(EM, maskedDBLen, H, hLen, Hash);

  p = EM;

  /* Initial PS XORs with all zeroes which is a NOP so just update
   * pointer. Note from a test above this value is guaranteed to
   * be non-negative.
   */
  p += emLen - sLen - hLen - 2;
  *p++ ^= 0x1;
  if (sLen > 0)
    {
    for (i = 0; i < sLen; i++)
      *p++ ^= salt[i];
    }
  if (MSBits)
    EM[0] &= 0xFF >> (8 - MSBits);

  /* H is already in place so just set final 0xbc */

  EM[emLen - 1] = 0xbc;

  ret = 1;

  err:
  if (salt)
    OPENSSL_free(salt);

  return ret;

  }
Ejemplo n.º 17
0
_SCAPI_NOT_CONFIGURED
#endif							/* */


/* sc_hash(): a generic wrapper around whatever hashing package we are using.

   IN:
     hashtype    - oid pointer to a hash type
     hashtypelen - length of oid pointer
     buf         - u_char buffer to be hashed
     buf_len     - integer length of buf data
     MAC_len     - length of the passed MAC buffer size.
    
   OUT:    
     MAC         - pre-malloced space to store hash output.
     MAC_len     - length of MAC output to the MAC buffer.

   Returns:
     SNMPERR_SUCCESS		Success.
     SNMP_SC_GENERAL_FAILURE	Any error.
*/

int
sc_hash(oid *hashtype, size_t hashtypelen, u_char *buf, size_t buf_len,
        u_char *MAC, size_t *MAC_len)
#if defined(USE_INTERNAL_MD5) || defined(USE_OPENSSL)
{
  int   rval       = SNMPERR_SUCCESS;

#ifdef USE_OPENSSL 
  EVP_MD *hash(void);
  HMAC_CTX *c = NULL; 
#endif

  DEBUGTRACE;

  if (hashtype == NULL || hashtypelen < 0 || buf == NULL ||
      buf_len < 0 || MAC == NULL ||  MAC_len == NULL ||
      (int)(*MAC_len) < sc_get_properlength(hashtype, hashtypelen))
    return (SNMPERR_GENERR);

#ifdef USE_OPENSSL 
  /*
   * Determine transform type.
   */
  c = malloc(sizeof(HMAC_CTX));
  if (c == NULL)
    return (SNMPERR_GENERR);

  if (ISTRANSFORM(hashtype, HMACMD5Auth)) {
    EVP_DigestInit(&c->md_ctx, (const EVP_MD *) EVP_md5());
  }
  else if (ISTRANSFORM(hashtype, HMACSHA1Auth)) {
    EVP_DigestInit(&c->md_ctx, (const EVP_MD *) EVP_sha1());
  }
  else {
    return(SNMPERR_GENERR);
  }
  EVP_DigestUpdate(&c->md_ctx, buf, buf_len);
  EVP_DigestFinal(&(c->md_ctx), MAC, MAC_len);
  free(c);
  return (rval);
#else /* USE_INTERNAL_MD5 */

  if (MDchecksum(buf, buf_len, MAC, *MAC_len)) {
    return SNMPERR_GENERR;
  }
  if (*MAC_len > 16)
    *MAC_len = 16;
  return SNMPERR_SUCCESS;

#endif /* USE_OPENSSL */
}
Ejemplo n.º 18
0
/*******************************************************************-o-******
 * generate_Ku
 *
 * Parameters:
 *	*hashtype	MIB OID for the transform type for hashing.
 *	 hashtype_len	Length of OID value.
 *	*P		Pre-allocated bytes of passpharase.
 *	 pplen		Length of passphrase.
 *	*Ku		Buffer to contain Ku.
 *	*kulen		Length of Ku buffer.
 *
 * Returns:
 *	SNMPERR_SUCCESS			Success.
 *	SNMPERR_GENERR			All errors.
 *
 *
 * Convert a passphrase into a master user key, Ku, according to the
 * algorithm given in RFC 2274 concerning the SNMPv3 User Security Model (USM)
 * as follows:
 *
 * Expand the passphrase to fill the passphrase buffer space, if necessary,
 * concatenation as many duplicates as possible of P to itself.  If P is
 * larger than the buffer space, truncate it to fit.
 *
 * Then hash the result with the given hashtype transform.  Return
 * the result as Ku.
 *
 * If successful, kulen contains the size of the hash written to Ku.
 *
 * NOTE  Passphrases less than USM_LENGTH_P_MIN characters in length
 *	 cause an error to be returned.
 *	 (Punt this check to the cmdline apps?  XXX)
 */
int
generate_Ku(	oid	*hashtype,	u_int  hashtype_len,
                u_char	*P,		size_t  pplen,
                u_char	*Ku,		size_t *kulen)
#if defined(USE_INTERNAL_MD5) || defined(USE_OPENSSL)
{
    int		 rval   = SNMPERR_SUCCESS,
             nbytes = USM_LENGTH_EXPANDED_PASSPHRASE;

    u_int            i, pindex = 0;

    u_char		 buf[USM_LENGTH_KU_HASHBLOCK],
                 *bufp;

#ifdef USE_OPENSSL
    EVP_MD_CTX      *ctx = malloc(sizeof(EVP_MD_CTX));
#else
    MDstruct         MD;
#endif
    /*
     * Sanity check.
     */
    if ( !hashtype || !P || !Ku || !kulen
            || (*kulen<=0)
            || (hashtype_len != USM_LENGTH_OID_TRANSFORM) )
    {
        QUITFUN(SNMPERR_GENERR, generate_Ku_quit);
    }

    if (pplen < USM_LENGTH_P_MIN) {
#ifdef SNMP_TESTING_CODE
        snmp_log(LOG_WARNING, "Warning: passphrase chosen is below the length requiremnts of the USM.\n");
#else
        snmp_set_detail("Password length too short.");
        QUITFUN(SNMPERR_GENERR, generate_Ku_quit);
#endif
    }


    /*
     * Setup for the transform type.
     */
#ifdef USE_OPENSSL

    if (ISTRANSFORM(hashtype, HMACMD5Auth))
        EVP_DigestInit(ctx, EVP_md5());
    else if (ISTRANSFORM(hashtype, HMACSHA1Auth))
        EVP_DigestInit(ctx, EVP_sha1());
    else  {
        free(ctx);
        return (SNMPERR_GENERR);
    }
#else
    MDbegin(&MD);
#endif /* USE_OPENSSL */

    while (nbytes > 0) {
        bufp = buf;
        for (i = 0; i < USM_LENGTH_KU_HASHBLOCK; i++) {
            *bufp++ = P[pindex++ % pplen];
        }
#ifdef USE_OPENSSL
        EVP_DigestUpdate(ctx, buf, USM_LENGTH_KU_HASHBLOCK);
#else
        if (MDupdate(&MD, buf, USM_LENGTH_KU_HASHBLOCK*8)) {
            rval = SNMPERR_USM_ENCRYPTIONERROR;
            goto md5_fin;
        }
#endif /* USE_OPENSSL */

        nbytes -= USM_LENGTH_KU_HASHBLOCK;
    }

#ifdef USE_OPENSSL
    EVP_DigestFinal(ctx, (unsigned char *) Ku, (unsigned int *) kulen);
    /* what about free() */
#else
    if (MDupdate(&MD, buf, 0)) {
        rval = SNMPERR_USM_ENCRYPTIONERROR;
        goto md5_fin;
    }
    *kulen = sc_get_properlength(hashtype, hashtype_len);
    MDget(&MD, Ku, *kulen);
md5_fin:
    memset(&MD, 0, sizeof(MD));
#endif /* USE_OPENSSL */


#ifdef SNMP_TESTING_CODE
    DEBUGMSGTL(("generate_Ku", "generating Ku (from %s): ", P));
    for(i=0; i < *kulen; i++)
        DEBUGMSG(("generate_Ku", "%02x",Ku[i]));
    DEBUGMSG(("generate_Ku","\n"));
#endif /* SNMP_TESTING_CODE */


generate_Ku_quit:
    memset(buf, 0, sizeof(buf));
#ifdef USE_OPENSSL
    free(ctx);
#endif
    return rval;

}  /* end generate_Ku() */
Ejemplo n.º 19
0
/*++
 * Function:	Get_Server_conn
 *
 * Purpose:	When a client login attempt is made, fetch a usable server
 *              connection descriptor.  This means that either we reuse an
 *              existing ICD, or we open a new one.  Hide that abstraction from
 *              the caller...
 *
 * Parameters:	ptr to username string
 *		ptr to password string
 *              const ptr to client hostname or IP string (for logging only)
 *              in_port_t, client port number (for logging only)
 *              unsigned char - flag to indicate that the client sent the
 *                              password as a string literal.
 *
 * Returns:	ICD * on success
 *              NULL on failure
 *
 * Authors:	Dave McMurtrie <*****@*****.**>
 *
 * Credit:      Major SSL additions by Ken Murchison <*****@*****.**>
 *
 *--
 */
extern ICD_Struct *Get_Server_conn( char *Username, 
				    char *Password,
				    const char *ClientAddr,
				    in_port_t sin_port,
				    unsigned char LiteralPasswd )
{
    char *fn = "Get_Server_conn()";
    unsigned int HashIndex;
    ICC_Struct *HashEntry = NULL;
    char SendBuf[BUFSIZE];
    unsigned int BufLen = BUFSIZE - 1;
    char md5pw[MD5_DIGEST_LENGTH];
    char *tokenptr;
    char *endptr;
    char *last;
    ICC_Struct *ICC_Active;
    ICC_Struct *ICC_tptr;
    ITD_Struct Server;
    int rc;
    unsigned int Expiration;

    EVP_MD_CTX mdctx;
    int md_len;

    Expiration = PC_Struct.cache_expiration_time;
    memset( &Server, 0, sizeof Server );
    
    /* need to md5 the passwd regardless, so do that now */
    EVP_DigestInit(&mdctx, EVP_md5());
    EVP_DigestUpdate(&mdctx, Password, strlen(Password));
    EVP_DigestFinal(&mdctx, md5pw, &md_len);
    
    /* see if we have a reusable connection available */
    ICC_Active = NULL;
    HashIndex = Hash( Username, HASH_TABLE_SIZE );
    
    LockMutex( &mp );
        
    /*
     * Now we just iterate through the linked list at this hash index until
     * we either find the string we're looking for or we find a NULL.
     */
    for ( HashEntry = ICC_HashTable[ HashIndex ]; 
	  HashEntry; 
	  HashEntry = HashEntry->next )
    {
	if ( ( strcmp( Username, HashEntry->username ) == 0 ) &&
	     ( HashEntry->logouttime > 1 ) )
	{
	    ICC_Active = HashEntry;
	    /*
	     * we found this username in our hash table.  Need to know if
	     * the password matches.
	     */
	    if ( memcmp( md5pw, ICC_Active->hashedpw, sizeof md5pw ) )
	    {
		syslog( LOG_NOTICE, "%s: Unable to reuse server sd [%d] for user '%s' (%s:%d) because password doesn't match.", fn, ICC_Active->server_conn->sd, Username, ClientAddr, sin_port );
		ICC_Active->logouttime = 1;
	    }
	    else
	    {
		/*
		 * We found a matching password on an inactive server socket.
		 * We can use this guy.  Before we release the mutex, set the
		 * logouttime such that we mark this connection as "active"
		 * again.
		 */
		ICC_Active->logouttime = 0;
	
		/*
		 * The fact that we have this stored in a table as an open
		 * server socket doesn't really mean that it's open.  The
		 * server could've closed it on us.
		 * We need a speedy way to make sure this is still open.
		 * We'll set the fd to non-blocking and try to read from it.
		 * If we get a zero back, the connection is closed.  If we get
		 * EWOULDBLOCK (or some data) we know it's still open.  If we
		 * do read data, make sure we read all the data so we "drain"
		 * any puss that may be left on this socket.
		 */
		fcntl( ICC_Active->server_conn->sd, F_SETFL,
		       fcntl( ICC_Active->server_conn->sd, F_GETFL, 0) | O_NONBLOCK );
		
		while ( ( rc = IMAP_Read( ICC_Active->server_conn, Server.ReadBuf, 
				     sizeof Server.ReadBuf ) ) > 0 );
		
		if ( !rc )
		{
		    syslog(LOG_NOTICE, "%s: Unable to reuse server sd [%d] for user '%s' (%s:%d).  Connection closed by server.", fn, ICC_Active->server_conn->sd, Username, ClientAddr, sin_port );
		    ICC_Active->logouttime = 1;
		    continue;
		}
	    
		if ( errno != EWOULDBLOCK )
		{
		    syslog(LOG_NOTICE, "%s: Unable to reuse server sd [%d] for user '%s' (%s:%d). IMAP_read() error: %s", fn, ICC_Active->server_conn->sd, Username, ClientAddr, sin_port, strerror( errno ) );
		    ICC_Active->logouttime = 1;
		    continue;
		}
		
		fcntl( ICC_Active->server_conn->sd, F_SETFL, 
		       fcntl( ICC_Active->server_conn->sd, F_GETFL, 0) & ~O_NONBLOCK );
		
		/* now release the mutex and return the sd to the caller */
		UnLockMutex( &mp );

		/*
		 * We're reusing an existing server socket.  There are a few
		 * counters we have to deal with.
		 */
		IMAPCount->RetainedServerConnections--;
		IMAPCount->InUseServerConnections++;
		IMAPCount->TotalServerConnectionsReused++;
		
		if ( IMAPCount->InUseServerConnections >
		     IMAPCount->PeakInUseServerConnections )
		    IMAPCount->PeakInUseServerConnections = IMAPCount->InUseServerConnections;
	    
		syslog(LOG_INFO, "LOGIN: '******' (%s:%d) on existing sd [%d]", Username, ClientAddr, sin_port, ICC_Active->server_conn->sd );
		return( ICC_Active->server_conn );
	    }
	}
    }
    
    
    UnLockMutex( &mp );
    
    /*
     * We don't have an active connection for this user, or the password
     * didn't match.
     * Open a connection to the IMAP server so we can attempt to login 
     */
    Server.conn = ( ICD_Struct * ) malloc( sizeof ( ICD_Struct ) );
    memset( Server.conn, 0, sizeof ( ICD_Struct ) );
    Server.conn->sd = socket( PF_INET, SOCK_STREAM, IPPROTO_TCP );
    if ( Server.conn->sd == -1 )
    {
	syslog(LOG_INFO, "LOGIN: '******' (%s:%d) failed: Unable to open server socket: %s", Username, ClientAddr, sin_port, strerror( errno ) );
	goto fail;
    }

    if ( PC_Struct.send_tcp_keepalives )
    {
	int onoff = 1;
	setsockopt( Server.conn->sd, SOL_SOCKET, SO_KEEPALIVE, &onoff, sizeof onoff );
    }
    
    if ( connect( Server.conn->sd, (struct sockaddr *)&ISD.srv, 
		  sizeof(ISD.srv) ) == -1 )
    {
	syslog(LOG_INFO, "LOGIN: '******' (%s:%d) failed: Unable to connect to IMAP server: %s", Username, ClientAddr, sin_port, strerror( errno ) );
	goto fail;
    }
    
    
    /* Read & throw away the banner line from the server */
    
    if ( IMAP_Line_Read( &Server ) == -1 )
    {
	syslog(LOG_INFO, "LOGIN: '******' (%s:%d) failed: No banner line received from IMAP server", Username, ClientAddr, sin_port );
	goto fail;
    }


    /*
     * Do STARTTLS if necessary.
     */
#if HAVE_LIBSSL
    if ( PC_Struct.login_disabled )
    {
	snprintf( SendBuf, BufLen, "S0001 STARTTLS\r\n" );
	if ( IMAP_Write( Server.conn, SendBuf, strlen(SendBuf) ) == -1 )
	{
	    syslog(LOG_INFO, "STARTTLS failed: IMAP_Write() failed attempting to send STARTTLS command to IMAP server: %s", strerror( errno ) );
	    goto fail;
	}

	/*
	 * Read the server response
	 */
	if ( ( rc = IMAP_Line_Read( &Server ) ) == -1 )
	{
	    syslog(LOG_INFO, "STARTTLS failed: No response from IMAP server after sending STARTTLS command" );
	    goto fail;
	}
    
	/*
	 * Try to match up the tag in the server response to the client tag.
	 */
	endptr = Server.ReadBuf + rc;
    
	tokenptr = memtok( Server.ReadBuf, endptr, &last );
    
	if ( !tokenptr )
	{
	    /* 
	     * no tokens found in server response?  Not likely, but we still
	     * have to check.
	     */
	    syslog(LOG_INFO, "STARTTLS failed: server response to STARTTLS command contained no tokens." );
	    goto fail;
	}
    
	if ( memcmp( (const void *)tokenptr, (const void *)"S0001", 
		     strlen( tokenptr ) ) )
	{
	    /* 
	     * non-matching tag read back from the server... Lord knows what this
	     * is, so we'll fail.
	     */
	    syslog(LOG_INFO, "STARTTLS failed: server response to STARTTLS command contained non-matching tag." );
	    goto fail;
	}
    
	/*
	 * Now that we've matched the tags up, see if the response was 'OK'
	 */
	tokenptr = memtok( NULL, endptr, &last );
    
	if ( !tokenptr )
	{
	    /* again, not likely but we still have to check... */
	    syslog(LOG_INFO, "STARTTLS failed: Malformed server response to STARTTLS command" );
	    goto fail;
	}
    
	if ( memcmp( (const void *)tokenptr, "OK", 2 ) )
	{
	    /*
	     * If the server sent back a "NO" or "BAD", we can look at the actual
	     * server logs to figure out why.  We don't have to break our ass here
	     * putting the string back together just for the sake of logging.
	     */
	    syslog(LOG_INFO, "STARTTLS failed: non-OK server response to STARTTLS command" );
	    goto fail;
	}
    
	Server.conn->tls = SSL_new( tls_ctx );
	if ( Server.conn->tls == NULL )
	{
	    syslog(LOG_INFO, "STARTTLS failed: SSL_new() failed" );
	    goto fail;
	}
	    
	SSL_clear( Server.conn->tls );
	rc = SSL_set_fd( Server.conn->tls, Server.conn->sd );
	if ( rc == 0 )
	{
	    syslog(LOG_INFO, "STARTTLS failed: SSL_set_fd() failed: %d",
		   SSL_get_error( Server.conn->tls, rc ) );
	    goto fail;
	}

	SSL_set_connect_state( Server.conn->tls );
	rc = SSL_connect( Server.conn->tls );
	if ( rc <= 0 )
	{
	    syslog(LOG_INFO, "STARTTLS failed: SSL_connect() failed, %d: %s",
		   SSL_get_error( Server.conn->tls, rc ), SSLerrmessage() );
	    goto fail;
	}

	/* XXX Should we grab the session id for later reuse? */
    }
#endif /* HAVE_LIBSSL */


    /*
     * Send the login command off to the IMAP server.  Have to treat a literal
     * password different.
     */
    if ( LiteralPasswd )
    {
	snprintf( SendBuf, BufLen, "A0001 LOGIN %s {%d}\r\n", 
		  Username, strlen( Password ) );
	if ( IMAP_Write( Server.conn, SendBuf, strlen(SendBuf) ) == -1 )
	{
	    syslog(LOG_INFO, "LOGIN: '******' (%s:%d) failed: IMAP_Write() failed attempting to send LOGIN command to IMAP server: %s", Username, ClientAddr, sin_port, strerror( errno ) );
	    goto fail;
	}
	
	/*
	 * the server response should be a go ahead
	 */
	if ( ( rc = IMAP_Line_Read( &Server ) ) == -1 )
	{
	    syslog(LOG_INFO, "LOGIN: '******' (%s:%d) failed: Failed to receive go-ahead from IMAP server after sending LOGIN command", Username, ClientAddr, sin_port );
	    goto fail;
	}
	
	if ( Server.ReadBuf[0] != '+' )
	{
	    syslog( LOG_INFO, "LOGIN: '******' (%s:%d) failed: bad response from server after sending string literal specifier", Username, ClientAddr, sin_port );
	    goto fail;
	}
	
	/* 
	 * now send the password
	 */
	snprintf( SendBuf, BufLen, "%s\r\n", Password );
	
	if ( IMAP_Write( Server.conn, SendBuf, strlen( SendBuf ) ) == -1 )
	{
	    syslog(LOG_INFO, "LOGIN: '******' (%s:%d) failed: IMAP_Write() failed attempting to send literal password to IMAP server: %s", Username, ClientAddr, sin_port, strerror( errno ) );
	    goto fail;
	}
    }
    else
    {
	/*
	 * just send the login command via normal means.
	 */
	snprintf( SendBuf, BufLen, "A0001 LOGIN %s %s\r\n", 
		  Username, Password );
	
	if ( IMAP_Write( Server.conn, SendBuf, strlen(SendBuf) ) == -1 )
	{
	    syslog(LOG_INFO, "LOGIN: '******' (%s:%d) failed: IMAP_Write() failed attempting to send LOGIN command to IMAP server: %s", Username, ClientAddr, sin_port, strerror( errno ) );
	    goto fail;
	}
    }
    
	
    /*
     * Read the server response.  From RFC 3501:
     *
     * A server MAY include a CAPABILITY response code in the tagged OK
     * response to a successful LOGIN command in order to send
     * capabilities automatically.  It is unnecessary for a client to
     * send a separate CAPABILITY command if it recognizes these
     * automatic capabilities.
     *
     * We have to be ready for the possibility that this might be an 
     * untagged response...  In an ideal world, we'd want to pass the
     * untagged stuff back to the client.  For now, since the RFC doesn't
     * mandate that behaviour, we're not going to since we don't have a client
     * socket descriptor to send it to.
     */
    for ( ;; )
    {
	if ( ( rc = IMAP_Line_Read( &Server ) ) == -1 )
	{
	    syslog(LOG_INFO, "LOGIN: '******' (%s:%d) failed: No response from IMAP server after sending LOGIN command", Username, ClientAddr, sin_port );
	    goto fail;
	}
    
	if ( Server.ReadBuf[0] != '*' )
	    break;
    }
    
    
    /*
     * Try to match up the tag in the server response to the client tag.
     */
    endptr = Server.ReadBuf + rc;
    
    tokenptr = memtok( Server.ReadBuf, endptr, &last );
    
    if ( !tokenptr )
    {
	/* 
	 * no tokens found in server response?  Not likely, but we still
	 * have to check.
	 */
	syslog(LOG_INFO, "LOGIN: '******' (%s:%d) failed: server response to LOGIN command contained no tokens.", Username, ClientAddr, sin_port );
	goto fail;
    }
    
    if ( memcmp( (const void *)tokenptr, (const void *)"A0001", 
		 strlen( tokenptr ) ) )
    {
	/* 
	 * non-matching tag read back from the server... Lord knows what this
	 * is, so we'll fail.
	 */
	syslog(LOG_INFO, "LOGIN: '******' (%s:%d) failed: server response to LOGIN command contained non-matching tag.", Username, ClientAddr, sin_port );
	goto fail;
    }
    
    
    /*
     * Now that we've matched the tags up, see if the response was 'OK'
     */
    tokenptr = memtok( NULL, endptr, &last );
    
    if ( !tokenptr )
    {
	/* again, not likely but we still have to check... */
	syslog(LOG_INFO, "LOGIN: '******' (%s:%d) failed: Malformed server response to LOGIN command", Username, ClientAddr, sin_port );
	goto fail;
    }
    
    if ( memcmp( (const void *)tokenptr, "OK", 2 ) )
    {
	/*
	 * If the server sent back a "NO" or "BAD", we can look at the actual
	 * server logs to figure out why.  We don't have to break our ass here
	 * putting the string back together just for the sake of logging.
	 */
	syslog(LOG_INFO, "LOGIN: '******' (%s:%d) failed: non-OK server response to LOGIN command", Username, ClientAddr, sin_port );
	goto fail;
    }
    
    /*
     * put this in our used list and remove it from the free list
     */
    for( ; ; )
    {
	LockMutex( &mp );
	
	if ( ICC_free->next )
	{
	    /* generate the hash index */
	    HashIndex = Hash( Username, HASH_TABLE_SIZE );
	    
	    /* temporarily store the address of the next free structure */
	    ICC_tptr = ICC_free->next;
	    
	    /*
	     * We want to add the newest "used" structure at the front of
	     * the list at the hash index.
	     */
	    ICC_free->next = ICC_HashTable[ HashIndex ];
	    ICC_HashTable[ HashIndex ] = ICC_free;
	    
	    /* 
	     * less typing and more readability, set an "active" pointer.
	     */
	    ICC_Active = ICC_free;
	    
	    /* now point the free listhead to the next available free struct */
	    ICC_free = ICC_tptr;
	    
	    /* fill in the newest used (oxymoron?) structure */
	    strncpy( ICC_Active->username, Username, 
		     sizeof ICC_Active->username );
	    memcpy( ICC_Active->hashedpw, md5pw, sizeof ICC_Active->hashedpw );
	    ICC_Active->logouttime = 0;    /* zero means, "it's active". */
	    ICC_Active->server_conn = Server.conn;
	    
	    UnLockMutex( &mp );
	    
	    IMAPCount->InUseServerConnections++;
	    IMAPCount->TotalServerConnectionsCreated++;

	    if ( IMAPCount->InUseServerConnections >
		 IMAPCount->PeakInUseServerConnections )
		IMAPCount->PeakInUseServerConnections = IMAPCount->InUseServerConnections;
	    syslog(LOG_INFO, "LOGIN: '******' (%s:%d) on new sd [%d]", Username, ClientAddr, sin_port, Server.conn->sd );
	    return( Server.conn );
	}
	
	/*
	 * There weren't any free ICC structs.  Try to free one.  Make sure
	 * we unlock the mutex, since ICC_Recycle needs to obtain it.
	 */
	UnLockMutex( &mp );
	
	Expiration = abs( Expiration / 2 );
	
	/*
	 * Eventually, we have to fail
	 */
	if ( Expiration <= 2 )
	{
	    syslog(LOG_INFO, "LOGIN: '******' (%s:%d) failed: Out of free ICC structs.", Username, ClientAddr, sin_port );
	    goto fail;
	}
	
	ICC_Recycle( Expiration );
	
    }
    
  fail:
#if HAVE_LIBSSL
    if ( Server.conn->tls )
    {
	SSL_shutdown( Server.conn->tls );
	SSL_free( Server.conn->tls );
    }
#endif
    close( Server.conn->sd );
    free( Server.conn );
    return( NULL );
}
Ejemplo n.º 20
0
// SHA-1(160bit)/SHA-256(256bit)を求める
unsigned char *kex_dh_gex_hash(const EVP_MD *evp_md,
                               char *client_version_string,
                               char *server_version_string,
                               char *ckexinit, int ckexinitlen,
                               char *skexinit, int skexinitlen,
                               u_char *serverhostkeyblob, int sbloblen,
                               int kexgex_min,
                               int kexgex_bits,
                               int kexgex_max,
                               BIGNUM *kexgex_p,
                               BIGNUM *kexgex_g,
                               BIGNUM *client_dh_pub,
                               BIGNUM *server_dh_pub,
                               BIGNUM *shared_secret,
                               unsigned int *hashlen)
{
	buffer_t *b;
	static unsigned char digest[EVP_MAX_MD_SIZE];
	EVP_MD_CTX md;

	b = buffer_init();
	buffer_put_string(b, client_version_string, strlen(client_version_string));
	buffer_put_string(b, server_version_string, strlen(server_version_string));

	/* kexinit messages: fake header: len+SSH2_MSG_KEXINIT */
	buffer_put_int(b, ckexinitlen+1);
	buffer_put_char(b, SSH2_MSG_KEXINIT);
	buffer_append(b, ckexinit, ckexinitlen);
	buffer_put_int(b, skexinitlen+1);
	buffer_put_char(b, SSH2_MSG_KEXINIT);
	buffer_append(b, skexinit, skexinitlen);

	buffer_put_string(b, serverhostkeyblob, sbloblen);

	// DH group sizeのビット数を加算する
	buffer_put_int(b, kexgex_min);
	buffer_put_int(b, kexgex_bits);
	buffer_put_int(b, kexgex_max);

	// DH鍵の素数と生成元を加算する
	buffer_put_bignum2(b, kexgex_p);
	buffer_put_bignum2(b, kexgex_g);

	buffer_put_bignum2(b, client_dh_pub);
	buffer_put_bignum2(b, server_dh_pub);
	buffer_put_bignum2(b, shared_secret);

	// yutaka
	//debug_print(38, buffer_ptr(b), buffer_len(b));

	EVP_DigestInit(&md, evp_md);
	EVP_DigestUpdate(&md, buffer_ptr(b), buffer_len(b));
	EVP_DigestFinal(&md, digest, NULL);

	buffer_free(b);

	//write_buffer_file(digest, EVP_MD_size(evp_md));

	*hashlen = EVP_MD_size(evp_md);

	return digest;
}
Ejemplo n.º 21
0
static int
derive_key(struct ssh *ssh, int id, u_int need, u_char *hash, u_int hashlen,
    BIGNUM *shared_secret, u_char **keyp)
{
	Kex *kex = ssh->kex;
	struct sshbuf *b = NULL;
	EVP_MD_CTX md;
	char c = id;
	u_int have;
	u_char *digest = NULL;
	int r, mdsz;

	if ((mdsz = EVP_MD_size(kex->evp_md)) <= 0)
		return SSH_ERR_INVALID_ARGUMENT;
	if ((digest = calloc(1, roundup(need, mdsz))) == NULL ||
	    (b = sshbuf_new()) == NULL) {
		r = SSH_ERR_ALLOC_FAIL;
		goto out;
	}
	if ((r = sshbuf_put_bignum2(b, shared_secret)) != 0)
		goto out;

	/* K1 = HASH(K || H || "A" || session_id) */
	if (EVP_DigestInit(&md, kex->evp_md) != 1 ||
	    (!(ssh->compat & SSH_BUG_DERIVEKEY) &&
	    EVP_DigestUpdate(&md, sshbuf_ptr(b), sshbuf_len(b)) != 1) ||
	    EVP_DigestUpdate(&md, hash, hashlen) != 1 ||
	    EVP_DigestUpdate(&md, &c, 1) != 1 ||
	    EVP_DigestUpdate(&md, kex->session_id, kex->session_id_len) != 1 ||
	    EVP_DigestFinal(&md, digest, NULL) != 1) {
		r = SSH_ERR_LIBCRYPTO_ERROR;
		goto out;
	}

	/*
	 * expand key:
	 * Kn = HASH(K || H || K1 || K2 || ... || Kn-1)
	 * Key = K1 || K2 || ... || Kn
	 */
	for (have = mdsz; need > have; have += mdsz) {
		if (EVP_DigestInit(&md, kex->evp_md) != 1 ||
		    (!(ssh->compat & SSH_BUG_DERIVEKEY) &&
		    EVP_DigestUpdate(&md, sshbuf_ptr(b), sshbuf_len(b)) != 1) ||
		    EVP_DigestUpdate(&md, hash, hashlen) != 1 ||
		    EVP_DigestUpdate(&md, digest, have) != 1 ||
		    EVP_DigestFinal(&md, digest + have, NULL) != 1) {
			r = SSH_ERR_LIBCRYPTO_ERROR;
			goto out;
		}
	}
#ifdef DEBUG_KEX
	fprintf(stderr, "key '%c'== ", c);
	dump_digest("key", digest, need);
#endif
	*keyp = digest;
	digest = NULL;
	r = 0;
 out:
	if (digest)
		free(digest);
	if (b)
		sshbuf_free(b);
	return r;
}
Ejemplo n.º 22
0
char* key_fingerprint_raw(Key *k, enum fp_type dgst_type, int *dgst_raw_length)
{
	const EVP_MD *md = NULL;
	EVP_MD_CTX ctx;
	char *blob = NULL;
	char *retval = NULL;
	int len = 0;
	int nlen, elen;
	RSA *rsa;

	*dgst_raw_length = 0;

	switch (dgst_type) {
	case SSH_FP_MD5:
		md = EVP_md5();
		break;
	case SSH_FP_SHA1:
		md = EVP_sha1();
		break;
	case SSH_FP_SHA256:
		md = EVP_sha256();
		break;
	default:
		md = EVP_md5();
	}

	switch (k->type) {
	case KEY_RSA1:
		rsa = make_key(NULL, k->bits, k->exp, k->mod);
		nlen = BN_num_bytes(rsa->n);
		elen = BN_num_bytes(rsa->e);
		len = nlen + elen;
		blob = malloc(len);
		if (blob == NULL) {
			// TODO:
		}
		BN_bn2bin(rsa->n, blob);
		BN_bn2bin(rsa->e, blob + nlen);
		RSA_free(rsa);
		break;

	case KEY_DSA:
	case KEY_RSA:
	case KEY_ECDSA256:
	case KEY_ECDSA384:
	case KEY_ECDSA521:
	case KEY_ED25519:
		key_to_blob(k, &blob, &len);
		break;

	case KEY_UNSPEC:
		return retval;
		break;

	default:
		//fatal("key_fingerprint_raw: bad key type %d", k->type);
		break;
	}

	if (blob != NULL) {
		retval = malloc(EVP_MAX_MD_SIZE);
		if (retval == NULL) {
			// TODO:
		}
		EVP_DigestInit(&ctx, md);
		EVP_DigestUpdate(&ctx, blob, len);
		EVP_DigestFinal(&ctx, retval, dgst_raw_length);
		memset(blob, 0, len);
		free(blob);
	} else {
		//fatal("key_fingerprint_raw: blob is null");
	}
	return retval;
}
Ejemplo n.º 23
0
int main(int argc, char *argv[]) {
	TSS_HCONTEXT hContext;
	TSS_RESULT result;
	TSS_HTPM hTPM;
	TSS_HPOLICY hPolicy;
	char *credential_filename = DEFAULT_CREDENTIAL_FILENAME;
	UINT32 nonceVerifierLength;
	BYTE *nonceVerifier;
	TSS_HDAA hDAA;
	TSS_DAA_CREDENTIAL *hDaaCredential;
	TSS_DAA_SIGN_DATA signData;
	TSS_DAA_SIGNATURE daaSignature;
	TSS_DAA_SELECTED_ATTRIB revealAttributes;
	char *szTpmPasswd = DEFAULT_OWN_PASSWD;
	char *message = NULL;
	BYTE **attributes = NULL;
	FILE *file;
	char *param;
	int i, length, rv;
	bi_ptr random = NULL;
	TSS_BOOL isCorrect;
	EVP_MD_CTX *mdctx;
	TSS_HKEY hKEY;

	init_tss_version( &signData);
	init_tss_version( &daaSignature);
	init_tss_version( &revealAttributes);
	i = 1;
	while( i < argc) {
		param = argv[ i];
		if ( strcmp( param, "-m") == 0 || strcmp( param, "--message") == 0) {
			i++;
			if( i == argc) return print_usage( argv[0]);
			message = argv[i];
		} else if( strcmp( param, "-cr") == 0 || strcmp( param, "--credential") == 0){
			i++;
			if( i == argc) return print_usage( argv[0]);
			credential_filename = argv[i];
		} else if( strcmp( param, "-pw") == 0 || strcmp( param, "--passwd") == 0){
			i++;
			if( i == argc) return print_usage( argv[0]);
			szTpmPasswd = argv[i];
		} else {
			fprintf(stderr, "%s:unrecognized option `%s'\n", argv[0], param);
			return print_usage( argv[0]);
		}
		i++;
	}
	bi_init( NULL);
	printf("Loading credential: %s ", credential_filename);
	file = fopen( credential_filename, "r");
	if( (hDaaCredential = load_TSS_DAA_CREDENTIAL( file)) == 0) {
		LogError( "[test_join]: Error when loading \'%s\': %s\n",
			credential_filename,
			strerror( errno));
		result = TSS_E_FAIL;
		goto out_close;
	}
	fclose( file);
	printf("Done\n");

	// Create Context
	LogDebug("Create Context");
	result = Tspi_Context_Create( &hContext );
	if ( result != TSS_SUCCESS )
	{
		LogError( "Tspi_Context_Create %d\n", result );
		goto out;
	}
	// Connect to Context
	result = Tspi_Context_Connect( hContext, NULL );
	if ( result != TSS_SUCCESS) goto out_close;
	printf("\nConnect to the context: %X\n", hContext);

	if( (result = Tspi_Context_GetTpmObject( hContext, &hTPM)) != TSS_SUCCESS)
		goto out_close;
	// Get the correct policy using the TPM ownership PASSWD
	if( (result = Tspi_GetPolicyObject( hTPM, TSS_POLICY_USAGE, &hPolicy)) != TSS_SUCCESS)
		goto out_close;
	if( (result = Tspi_Policy_SetSecret( hPolicy,
						TSS_SECRET_MODE_PLAIN,
						strlen( szTpmPasswd),
						szTpmPasswd)) != TSS_SUCCESS)
		goto out_close;
	LogDebug("Tspi_Policy_SetSecret hPolicy received;%d", hPolicy);

	//Create Object
	result = obj_daa_add( hContext, &hDAA);
	if (result != TSS_SUCCESS) {
		LogError("Tspi_Context_CreateObject:%d", result);
		Tspi_Context_Close(hContext);
		LogError("%s: %s", argv[0], err_string(result));
		exit(result);
	}
	LogDebug("created DAA object:%X", hDAA);

	// TODO: verifier base name ??
	result = Tspi_DAA_VerifyInit(
		hDAA,	// in
		&nonceVerifierLength,	// out
		&nonceVerifier,	// out
		0, //baseNameLength,	// out
		NULL //baseName		// out
	);
	if (result != TSS_SUCCESS) goto out_close;
	LogDebug("Verify Init return nonceVerifier [%s]",
			dump_byte_array( nonceVerifierLength, nonceVerifier));

	create_TSS_DAA_SELECTED_ATTRIB( &revealAttributes, 5, 0, 1, 1, 0, 0);

	mdctx = EVP_MD_CTX_create();

	// create the TSS_DAA_SIGN_DATA struct
	// .selector: 0 -> payload contains a handle to an AIK
	//            1 -> payload contains a hashed message
	if( message != NULL) {
		signData.selector = TSS_FLAG_DAA_SIGN_MESSAGE_HASH;
		signData.payloadFlag = TSS_FLAG_DAA_SIGN_MESSAGE_HASH;
		EVP_DigestInit(mdctx, DAA_PARAM_get_message_digest());
		EVP_DigestUpdate(mdctx,  (BYTE *)message, strlen( message));
		signData.payloadLength = EVP_MD_CTX_size(mdctx);
		signData.payload = (BYTE *)EVP_MD_CTX_create();
		EVP_DigestFinal(mdctx, signData.payload, NULL);
	} else {
		signData.selector = TSS_FLAG_DAA_SIGN_IDENTITY_KEY;
		result = Tspi_Context_CreateObject(
			hContext,	 //  in
			TSS_OBJECT_TYPE_RSAKEY,		//  in
			TSS_KEY_SIZE_2048,		//  in
			&hKEY	//  out
		);
		if( result != TSS_SUCCESS) goto out_close;

	}

	result = Tspi_TPM_DAA_Sign(
		hDAA,	// in
		hTPM,	// in
		(TSS_HKEY)hDaaCredential,	// in
		revealAttributes,	// in
		0, // verifierBaseNameLength,	// in
		NULL, // verifierBaseName,	// in
		nonceVerifierLength,	// in
		nonceVerifier,	// in
		signData,	// in
		&daaSignature	// out
	);
	if (result != TSS_SUCCESS) goto out_close;
	LogDebug("TPM_DAA_Sign return daaSignature [%s]",
			dump_byte_array( nonceVerifierLength, nonceVerifier));

	// generate attributes list but without copying the not revealed ones
	attributes = malloc( sizeof(BYTE *) * hDaaCredential->attributesLength);
	for( i=0; i < (int)(hDaaCredential->attributesLength); i++) {
		if( revealAttributes.indicesList[i]) {
			attributes[i] = (BYTE *)malloc( DAA_PARAM_SIZE_F_I / 8);
			memcpy( attributes[i],
				hDaaCredential->attributes[i],
				DAA_PARAM_SIZE_F_I / 8);
		} else {
			attributes[i] = NULL;
		}
	}

	result = Tspi_DAA_VerifySignature(
		hDAA,	// in
		daaSignature,	// in
		(TSS_HKEY)&(hDaaCredential->issuerPK),	// in
		signData,	// in
		hDaaCredential->attributesLength,	// in
		attributes,	// in
		nonceVerifierLength,	// in
		nonceVerifier,	// in
		0,	//baseNameLength,	//in
		NULL,	// in
		&isCorrect	// out
	);
	printf("Signature correct:%s\n", ( isCorrect ? "yes" : "no"));

out_close:
	EVP_MD_CTX_destroy(mdctx);
	if( attributes != NULL) {
		for( i=0; i<(int)hDaaCredential->attributesLength; i++) {
			if( attributes[i] != NULL) free( attributes[i]);
		}
		free( attributes);
	}
	if( random != NULL) bi_free_ptr( random);
	Tspi_Context_FreeMemory( hContext, NULL );
	Tspi_Context_Close( hContext );
out:
	bi_release();
	LogDebug("THE END result=%d:%s",result, err_string( result) );;
	return result;
}
Ejemplo n.º 24
0
int
ssh_rsa_verify(const Key *key, const u_char *signature, u_int signaturelen,
    const u_char *data, u_int datalen)
{
	Buffer b;
	const EVP_MD *evp_md;
	EVP_MD_CTX md;
	char *ktype;
	u_char digest[EVP_MAX_MD_SIZE], *sigblob;
	u_int len, dlen, modlen;
	int rlen, ret, nid;

	if (key == NULL ||
	    (key->type != KEY_RSA && key->type != KEY_RSA_CERT) ||
	    key->rsa == NULL) {
		error("ssh_rsa_verify: no RSA key");
		return -1;
	}
	if (BN_num_bits(key->rsa->n) < SSH_RSA_MINIMUM_MODULUS_SIZE) {
		error("ssh_rsa_verify: RSA modulus too small: %d < minimum %d bits",
		    BN_num_bits(key->rsa->n), SSH_RSA_MINIMUM_MODULUS_SIZE);
		return -1;
	}
	buffer_init(&b);
	buffer_append(&b, signature, signaturelen);
	ktype = buffer_get_string(&b, NULL);
	if (strcmp("ssh-rsa", ktype) != 0) {
		error("ssh_rsa_verify: cannot handle type %s", ktype);
		buffer_free(&b);
		xfree(ktype);
		return -1;
	}
	xfree(ktype);
	sigblob = buffer_get_string(&b, &len);
	rlen = buffer_len(&b);
	buffer_free(&b);
	if (rlen != 0) {
		error("ssh_rsa_verify: remaining bytes in signature %d", rlen);
		xfree(sigblob);
		return -1;
	}
	/* RSA_verify expects a signature of RSA_size */
	modlen = RSA_size(key->rsa);
	if (len > modlen) {
		error("ssh_rsa_verify: len %u > modlen %u", len, modlen);
		xfree(sigblob);
		return -1;
	} else if (len < modlen) {
		u_int diff = modlen - len;
		debug("ssh_rsa_verify: add padding: modlen %u > len %u",
		    modlen, len);
		sigblob = xrealloc(sigblob, 1, modlen);
		memmove(sigblob + diff, sigblob, len);
		memset(sigblob, 0, diff);
		len = modlen;
	}
	nid = (datafellows & SSH_BUG_RSASIGMD5) ? NID_md5 : NID_sha1;
	if ((evp_md = EVP_get_digestbynid(nid)) == NULL) {
		error("ssh_rsa_verify: EVP_get_digestbynid %d failed", nid);
		xfree(sigblob);
		return -1;
	}
	EVP_DigestInit(&md, evp_md);
	EVP_DigestUpdate(&md, data, datalen);
	EVP_DigestFinal(&md, digest, &dlen);

	ret = openssh_RSA_verify(nid, digest, dlen, sigblob, len, key->rsa);
	memset(digest, 'd', sizeof(digest));
	memset(sigblob, 's', len);
	xfree(sigblob);
	debug("ssh_rsa_verify: signature %scorrect", (ret==0) ? "in" : "");
	return ret;
}
Ejemplo n.º 25
0
/*******************************************************************-o-******
 * generate_Ku
 *
 * Parameters:
 *	*hashtype	MIB OID for the transform type for hashing.
 *	 hashtype_len	Length of OID value.
 *	*P		Pre-allocated bytes of passpharase.
 *	 pplen		Length of passphrase.
 *	*Ku		Buffer to contain Ku.
 *	*kulen		Length of Ku buffer.
 *      
 * Returns:
 *	SNMPERR_SUCCESS			Success.
 *	SNMPERR_GENERR			All errors.
 *
 *
 * Convert a passphrase into a master user key, Ku, according to the
 * algorithm given in RFC 2274 concerning the SNMPv3 User Security Model (USM)
 * as follows:
 *
 * Expand the passphrase to fill the passphrase buffer space, if necessary,
 * concatenation as many duplicates as possible of P to itself.  If P is
 * larger than the buffer space, truncate it to fit.
 *
 * Then hash the result with the given hashtype transform.  Return
 * the result as Ku.
 *
 * If successful, kulen contains the size of the hash written to Ku.
 *
 * NOTE  Passphrases less than USM_LENGTH_P_MIN characters in length
 *	 cause an error to be returned.
 *	 (Punt this check to the cmdline apps?  XXX)
 */
int
generate_Ku(const oid * hashtype, u_int hashtype_len,
            const u_char * P, size_t pplen, u_char * Ku, size_t * kulen)
#if defined(NETSNMP_USE_INTERNAL_MD5) || defined(NETSNMP_USE_OPENSSL) || defined(NETSNMP_USE_INTERNAL_CRYPTO)
{
    int             rval = SNMPERR_SUCCESS,
        nbytes = USM_LENGTH_EXPANDED_PASSPHRASE;
#if !defined(NETSNMP_USE_OPENSSL) && \
    defined(NETSNMP_USE_INTERNAL_MD5) || defined(NETSNMP_USE_INTERNAL_CRYPTO)
    int             ret;
#endif

    u_int           i, pindex = 0;

    u_char          buf[USM_LENGTH_KU_HASHBLOCK], *bufp;

#ifdef NETSNMP_USE_OPENSSL
    EVP_MD_CTX     *ctx = NULL;
#elif NETSNMP_USE_INTERNAL_CRYPTO
    SHA_CTX csha1;
    MD5_CTX cmd5;
    char    cryptotype = 0;
#define TYPE_MD5  1
#define TYPE_SHA1 2
#else
    MDstruct        MD;
#endif
    /*
     * Sanity check.
     */
    if (!hashtype || !P || !Ku || !kulen || (*kulen <= 0)
        || (hashtype_len != USM_LENGTH_OID_TRANSFORM)) {
        QUITFUN(SNMPERR_GENERR, generate_Ku_quit);
    }

    if (pplen < USM_LENGTH_P_MIN) {
        snmp_log(LOG_ERR, "Error: passphrase chosen is below the length "
                 "requirements of the USM (min=%d).\n",USM_LENGTH_P_MIN);
        snmp_set_detail("The supplied password length is too short.");
        QUITFUN(SNMPERR_GENERR, generate_Ku_quit);
    }


    /*
     * Setup for the transform type.
     */
#ifdef NETSNMP_USE_OPENSSL

#ifdef HAVE_EVP_MD_CTX_CREATE
    ctx = EVP_MD_CTX_create();
#else
    ctx = malloc(sizeof(*ctx));
    EVP_MD_CTX_init(ctx);
#endif
#ifndef NETSNMP_DISABLE_MD5
    if (ISTRANSFORM(hashtype, HMACMD5Auth))
        EVP_DigestInit(ctx, EVP_md5());
    else
#endif
        if (ISTRANSFORM(hashtype, HMACSHA1Auth))
        EVP_DigestInit(ctx, EVP_sha1());
    else
        QUITFUN(SNMPERR_GENERR, generate_Ku_quit);
#elif NETSNMP_USE_INTERNAL_CRYPTO
#ifndef NETSNMP_DISABLE_MD5
    if (ISTRANSFORM(hashtype, HMACMD5Auth)) {
        MD5_Init(&cmd5);
        cryptotype = TYPE_MD5;
    } else
#endif
           if (ISTRANSFORM(hashtype, HMACSHA1Auth)) {
        SHA1_Init(&csha1);
        cryptotype = TYPE_SHA1;
    } else {
        return (SNMPERR_GENERR);
    }
#else
    MDbegin(&MD);
#endif                          /* NETSNMP_USE_OPENSSL */

    while (nbytes > 0) {
        bufp = buf;
        for (i = 0; i < USM_LENGTH_KU_HASHBLOCK; i++) {
            *bufp++ = P[pindex++ % pplen];
        }
#ifdef NETSNMP_USE_OPENSSL
        EVP_DigestUpdate(ctx, buf, USM_LENGTH_KU_HASHBLOCK);
#elif NETSNMP_USE_INTERNAL_CRYPTO
        if (TYPE_SHA1 == cryptotype) {
            rval = !SHA1_Update(&csha1, buf, USM_LENGTH_KU_HASHBLOCK);
        } else {
            rval = !MD5_Update(&cmd5, buf, USM_LENGTH_KU_HASHBLOCK);
        }
        if (rval != 0) {
            return SNMPERR_USM_ENCRYPTIONERROR;
        }
#elif NETSNMP_USE_INTERNAL_MD5
        if (MDupdate(&MD, buf, USM_LENGTH_KU_HASHBLOCK * 8)) {
            rval = SNMPERR_USM_ENCRYPTIONERROR;
            goto md5_fin;
        }
#endif                          /* NETSNMP_USE_OPENSSL */
        nbytes -= USM_LENGTH_KU_HASHBLOCK;
    }

#ifdef NETSNMP_USE_OPENSSL
    {
    unsigned int    tmp_len;

    tmp_len = *kulen;
    EVP_DigestFinal(ctx, (unsigned char *) Ku, &tmp_len);
    *kulen = tmp_len;
    /*
     * what about free() 
     */
    }
#elif NETSNMP_USE_INTERNAL_CRYPTO
    if (TYPE_SHA1 == cryptotype) {
        SHA1_Final(Ku, &csha1);
    } else {
        MD5_Final(Ku, &cmd5);
    }
    ret = sc_get_properlength(hashtype, hashtype_len);
    if (ret == SNMPERR_GENERR)
        return SNMPERR_GENERR;
    *kulen = ret;
#elif NETSNMP_USE_INTERNAL_MD5
    if (MDupdate(&MD, buf, 0)) {
        rval = SNMPERR_USM_ENCRYPTIONERROR;
        goto md5_fin;
    }
    ret = sc_get_properlength(hashtype, hashtype_len);
    if (ret == SNMPERR_GENERR)
        return SNMPERR_GENERR;
    *kulen = ret;
    MDget(&MD, Ku, *kulen);
  md5_fin:
    memset(&MD, 0, sizeof(MD));
#endif                          /* NETSNMP_USE_INTERNAL_MD5 */


#ifdef NETSNMP_ENABLE_TESTING_CODE
    DEBUGMSGTL(("generate_Ku", "generating Ku (from %s): ", P));
    for (i = 0; i < *kulen; i++)
        DEBUGMSG(("generate_Ku", "%02x", Ku[i]));
    DEBUGMSG(("generate_Ku", "\n"));
#endif                          /* NETSNMP_ENABLE_TESTING_CODE */


  generate_Ku_quit:
    memset(buf, 0, sizeof(buf));
#ifdef NETSNMP_USE_OPENSSL
    if (ctx) {
#ifdef HAVE_EVP_MD_CTX_DESTROY
        EVP_MD_CTX_destroy(ctx);
#else
        EVP_MD_CTX_cleanup(ctx);
        free(ctx);
#endif
    }
#endif
    return rval;

}                               /* end generate_Ku() */
Ejemplo n.º 26
0
/* RSASSA-PKCS1-v1_5 (PKCS #1 v2.0 signature) with SHA1 */
int
ssh_rsa_sign(const Key *key, u_char **sigp, u_int *lenp,
    const u_char *data, u_int datalen)
{
	const EVP_MD *evp_md;
	EVP_MD_CTX md;
	u_char digest[EVP_MAX_MD_SIZE], *sig;
	u_int slen, dlen, len;
	int ok, nid;
	Buffer b;

	if (key == NULL ||
	    (key->type != KEY_RSA && key->type != KEY_RSA_CERT) ||
	    key->rsa == NULL) {
		error("ssh_rsa_sign: no RSA key");
		return -1;
	}
	nid = (datafellows & SSH_BUG_RSASIGMD5) ? NID_md5 : NID_sha1;
	if ((evp_md = EVP_get_digestbynid(nid)) == NULL) {
		error("ssh_rsa_sign: EVP_get_digestbynid %d failed", nid);
		return -1;
	}
	EVP_DigestInit(&md, evp_md);
	EVP_DigestUpdate(&md, data, datalen);
	EVP_DigestFinal(&md, digest, &dlen);

	slen = RSA_size(key->rsa);
	sig = xmalloc(slen);

	ok = RSA_sign(nid, digest, dlen, sig, &len, key->rsa);
	memset(digest, 'd', sizeof(digest));

	if (ok != 1) {
		int ecode = ERR_get_error();

		error("ssh_rsa_sign: RSA_sign failed: %s",
		    ERR_error_string(ecode, NULL));
		xfree(sig);
		return -1;
	}
	if (len < slen) {
		u_int diff = slen - len;
		debug("slen %u > len %u", slen, len);
		memmove(sig + diff, sig, len);
		memset(sig, 0, diff);
	} else if (len > slen) {
		error("ssh_rsa_sign: slen %u slen2 %u", slen, len);
		xfree(sig);
		return -1;
	}
	/* encode signature */
	buffer_init(&b);
	buffer_put_cstring(&b, "ssh-rsa");
	buffer_put_string(&b, sig, slen);
	len = buffer_len(&b);
	if (lenp != NULL)
		*lenp = len;
	if (sigp != NULL) {
		*sigp = xmalloc(len);
		memcpy(*sigp, buffer_ptr(&b), len);
	}
	buffer_free(&b);
	memset(sig, 's', slen);
	xfree(sig);

	return 0;
}
Ejemplo n.º 27
0
static int sb_verify_image_header(struct sb_image_ctx *ictx,
				  FILE *fp, long fsize)
{
	/* Verify static fields in the image header. */
	struct sb_boot_image_header *hdr = &ictx->payload;
	const char *stat[2] = { "[PASS]", "[FAIL]" };
	struct tm tm;
	int sz, ret = 0;
	unsigned char digest[20];
	EVP_MD_CTX md_ctx;
	unsigned long size;

	/* Start image-wide crypto. */
	EVP_MD_CTX_init(&ictx->md_ctx);
	EVP_DigestInit(&ictx->md_ctx, EVP_sha1());

	soprintf(ictx, "---------- Verifying SB Image Header ----------\n");

	size = fread(&ictx->payload, 1, sizeof(ictx->payload), fp);
	if (size != sizeof(ictx->payload)) {
		fprintf(stderr, "ERR: SB image header too short!\n");
		return -EINVAL;
	}

	/* Compute header digest. */
	EVP_MD_CTX_init(&md_ctx);
	EVP_DigestInit(&md_ctx, EVP_sha1());
	EVP_DigestUpdate(&md_ctx, hdr->signature1,
			 sizeof(struct sb_boot_image_header) -
			 sizeof(hdr->digest));
	EVP_DigestFinal(&md_ctx, digest, NULL);

	sb_aes_init(ictx, NULL, 1);
	sb_encrypt_sb_header(ictx);

	if (memcmp(digest, hdr->digest, 20))
		ret = -EINVAL;
	soprintf(ictx, "%s Image header checksum:        %s\n", stat[!!ret],
		 ret ? "BAD" : "OK");
	if (ret)
		return ret;

	if (memcmp(hdr->signature1, "STMP", 4) ||
	    memcmp(hdr->signature2, "sgtl", 4))
		ret = -EINVAL;
	soprintf(ictx, "%s Signatures:                   '%.4s' '%.4s'\n",
		 stat[!!ret], hdr->signature1, hdr->signature2);
	if (ret)
		return ret;

	if ((hdr->major_version != SB_VERSION_MAJOR) ||
	    ((hdr->minor_version != 1) && (hdr->minor_version != 2)))
		ret = -EINVAL;
	soprintf(ictx, "%s Image version:                v%i.%i\n", stat[!!ret],
		 hdr->major_version, hdr->minor_version);
	if (ret)
		return ret;

	ret = sb_get_time(hdr->timestamp_us / 1000000, &tm);
	soprintf(ictx,
		 "%s Creation time:                %02i:%02i:%02i %02i/%02i/%04i\n",
		 stat[!!ret], tm.tm_hour, tm.tm_min, tm.tm_sec,
		 tm.tm_mday, tm.tm_mon, tm.tm_year + 2000);
	if (ret)
		return ret;

	soprintf(ictx, "%s Product version:              %x.%x.%x\n", stat[0],
		 ntohs(hdr->product_version.major),
		 ntohs(hdr->product_version.minor),
		 ntohs(hdr->product_version.revision));
	soprintf(ictx, "%s Component version:            %x.%x.%x\n", stat[0],
		 ntohs(hdr->component_version.major),
		 ntohs(hdr->component_version.minor),
		 ntohs(hdr->component_version.revision));

	if (hdr->flags & ~SB_IMAGE_FLAGS_MASK)
		ret = -EINVAL;
	soprintf(ictx, "%s Image flags:                  %s\n", stat[!!ret],
		 hdr->flags & SB_IMAGE_FLAG_DISPLAY_PROGRESS ?
		 "Display_progress" : "");
	if (ret)
		return ret;

	if (hdr->drive_tag != 0)
		ret = -EINVAL;
	soprintf(ictx, "%s Drive tag:                    %i\n", stat[!!ret],
		 hdr->drive_tag);
	if (ret)
		return ret;

	sz = sizeof(struct sb_boot_image_header) / SB_BLOCK_SIZE;
	if (hdr->header_blocks != sz)
		ret = -EINVAL;
	soprintf(ictx, "%s Image header size (blocks):   %i\n", stat[!!ret],
		 hdr->header_blocks);
	if (ret)
		return ret;

	sz = sizeof(struct sb_sections_header) / SB_BLOCK_SIZE;
	if (hdr->section_header_size != sz)
		ret = -EINVAL;
	soprintf(ictx, "%s Section header size (blocks): %i\n", stat[!!ret],
		 hdr->section_header_size);
	if (ret)
		return ret;

	soprintf(ictx, "%s Sections count:               %i\n", stat[!!ret],
		 hdr->section_count);
	soprintf(ictx, "%s First bootable section        %i\n", stat[!!ret],
		 hdr->first_boot_section_id);

	if (hdr->image_blocks != fsize / SB_BLOCK_SIZE)
		ret = -EINVAL;
	soprintf(ictx, "%s Image size (blocks):          %i\n", stat[!!ret],
		 hdr->image_blocks);
	if (ret)
		return ret;

	sz = hdr->header_blocks + hdr->section_header_size * hdr->section_count;
	if (hdr->key_dictionary_block != sz)
		ret = -EINVAL;
	soprintf(ictx, "%s Key dict offset (blocks):     %i\n", stat[!!ret],
		 hdr->key_dictionary_block);
	if (ret)
		return ret;

	if (hdr->key_count != 1)
		ret = -EINVAL;
	soprintf(ictx, "%s Number of encryption keys:    %i\n", stat[!!ret],
		 hdr->key_count);
	if (ret)
		return ret;

	sz = hdr->header_blocks + hdr->section_header_size * hdr->section_count;
	sz += hdr->key_count *
		sizeof(struct sb_key_dictionary_key) / SB_BLOCK_SIZE;
	if (hdr->first_boot_tag_block != (unsigned)sz)
		ret = -EINVAL;
	soprintf(ictx, "%s First TAG block (blocks):     %i\n", stat[!!ret],
		 hdr->first_boot_tag_block);
	if (ret)
		return ret;

	return 0;
}
Ejemplo n.º 28
0
/** @impl_interface_method{RTCRDIGESTDESC::pfnFinal} */
static DECLCALLBACK(void) rtCrDigestOsslEvp_Final(void *pvState, uint8_t *pbHash)
{
    unsigned int cbHash = EVP_MAX_MD_SIZE;
    EVP_DigestFinal((EVP_MD_CTX *)pvState, (unsigned char *)pbHash, &cbHash);
}
Ejemplo n.º 29
0
int RSA_verify_PKCS1_PSS(RSA *rsa, const unsigned char *mHash,
      const EVP_MD *Hash, const unsigned char *EM, int sLen)
  {
  int i;
  int ret = 0;
  int hLen, maskedDBLen, MSBits, emLen;
  const unsigned char *H;
  unsigned char *DB = NULL;
  EVP_MD_CTX ctx;
  unsigned char H_[EVP_MAX_MD_SIZE];

  hLen = EVP_MD_size(Hash);
  /*
   * Negative sLen has special meanings:
   *  -1  sLen == hLen
   *  -2  salt length is autorecovered from signature
   *  -N  reserved
   */
  if      (sLen == -1)  sLen = hLen;
  else if (sLen == -2)  sLen = -2;
  else if (sLen < -2)
    {
    RSAerr(RSA_F_RSA_VERIFY_PKCS1_PSS, RSA_R_SLEN_CHECK_FAILED);
    goto err;
    }

  MSBits = (BN_num_bits(rsa->n) - 1) & 0x7;
  emLen = RSA_size(rsa);
  if (EM[0] & (0xFF << MSBits))
    {
    RSAerr(RSA_F_RSA_VERIFY_PKCS1_PSS, RSA_R_FIRST_OCTET_INVALID);
    goto err;
    }
  if (MSBits == 0)
    {
    EM++;
    emLen--;
    }
  if (emLen < (hLen + sLen + 2)) /* sLen can be small negative */
    {
    RSAerr(RSA_F_RSA_VERIFY_PKCS1_PSS, RSA_R_DATA_TOO_LARGE);
    goto err;
    }
  if (EM[emLen - 1] != 0xbc)
    {
    RSAerr(RSA_F_RSA_VERIFY_PKCS1_PSS, RSA_R_LAST_OCTET_INVALID);
    goto err;
    }
  maskedDBLen = emLen - hLen - 1;
  H = EM + maskedDBLen;
  DB = OPENSSL_malloc(maskedDBLen);
  if (!DB)
    {
    RSAerr(RSA_F_RSA_VERIFY_PKCS1_PSS, ERR_R_MALLOC_FAILURE);
    goto err;
    }
  PKCS1_MGF1(DB, maskedDBLen, H, hLen, Hash);
  for (i = 0; i < maskedDBLen; i++)
    DB[i] ^= EM[i];
  if (MSBits)
    DB[0] &= 0xFF >> (8 - MSBits);
  for (i = 0; DB[i] == 0 && i < (maskedDBLen-1); i++) ;
  if (DB[i++] != 0x1)
    {
    RSAerr(RSA_F_RSA_VERIFY_PKCS1_PSS, RSA_R_SLEN_RECOVERY_FAILED);
    goto err;
    }
  if (sLen >= 0 && (maskedDBLen - i) != sLen)
    {
    RSAerr(RSA_F_RSA_VERIFY_PKCS1_PSS, RSA_R_SLEN_CHECK_FAILED);
    goto err;
    }
  EVP_MD_CTX_init(&ctx);
  EVP_DigestInit_ex(&ctx, Hash, NULL);
  EVP_DigestUpdate(&ctx, zeroes, sizeof zeroes);
  EVP_DigestUpdate(&ctx, mHash, hLen);
  if (maskedDBLen - i)
    EVP_DigestUpdate(&ctx, DB + i, maskedDBLen - i);
  EVP_DigestFinal(&ctx, H_, NULL);
  EVP_MD_CTX_cleanup(&ctx);
  if (memcmp(H_, H, hLen))
    {
    RSAerr(RSA_F_RSA_VERIFY_PKCS1_PSS, RSA_R_BAD_SIGNATURE);
    ret = 0;
    }
  else 
    ret = 1;

  err:
  if (DB)
    OPENSSL_free(DB);

  return ret;

  }
Ejemplo n.º 30
0
static int sb_encrypt_image(struct sb_image_ctx *ictx)
{
	/* Start image-wide crypto. */
	EVP_MD_CTX_init(&ictx->md_ctx);
	EVP_DigestInit(&ictx->md_ctx, EVP_sha1());

	/*
	 * SB image header.
	 */
	sb_aes_init(ictx, NULL, 1);
	sb_encrypt_sb_header(ictx);

	/*
	 * SB sections header.
	 */
	sb_encrypt_sb_sections_header(ictx);

	/*
	 * Key dictionary.
	 */
	sb_aes_reinit(ictx, 1);
	sb_encrypt_key_dictionary_key(ictx);

	/*
	 * Section tags.
	 */
	struct sb_cmd_ctx *cctx;
	struct sb_command *ccmd;
	struct sb_section_ctx *sctx = ictx->sect_head;

	while (sctx) {
		cctx = sctx->cmd_head;

		sb_aes_reinit(ictx, 1);

		while (cctx) {
			ccmd = &cctx->payload;

			sb_encrypt_tag(ictx, cctx);

			if (ccmd->header.tag == ROM_TAG_CMD) {
				sb_aes_reinit(ictx, 1);
			} else if (ccmd->header.tag == ROM_LOAD_CMD) {
				sb_aes_crypt(ictx, cctx->data, cctx->data,
					     cctx->length);
				EVP_DigestUpdate(&ictx->md_ctx, cctx->data,
						 cctx->length);
			}

			cctx = cctx->cmd;
		}

		sctx = sctx->sect;
	};

	/*
	 * Dump the SHA1 of the whole image.
	 */
	sb_aes_reinit(ictx, 1);

	EVP_DigestFinal(&ictx->md_ctx, ictx->digest, NULL);
	sb_aes_crypt(ictx, ictx->digest, ictx->digest, sizeof(ictx->digest));

	/* Stop the encryption session. */
	sb_aes_deinit(&ictx->cipher_ctx);

	return 0;
}