Ejemplo n.º 1
1
bool OSSLRSA::verifyFinal(const ByteString& signature)
{
	// Save necessary state before calling super class verifyFinal
	OSSLRSAPublicKey* pk = (OSSLRSAPublicKey*) currentPublicKey;
	AsymMech::Type mechanism = currentMechanism;

	if (!AsymmetricAlgorithm::verifyFinal(signature))
	{
		return false;
	}

	ByteString firstHash, secondHash;

	bool bFirstResult = pCurrentHash->hashFinal(firstHash);
	bool bSecondResult = (pSecondHash != NULL) ? pSecondHash->hashFinal(secondHash) : true;

	delete pCurrentHash;
	pCurrentHash = NULL;

	if (pSecondHash != NULL)
	{
		delete pSecondHash;

		pSecondHash = NULL;
	}

	if (!bFirstResult || !bSecondResult)
	{
		return false;
	}

	ByteString digest = firstHash + secondHash;

	// Determine the signature NID type
	int type = 0;
	bool isPSS = false;
	const EVP_MD* hash = NULL;

	switch (mechanism)
	{
		case AsymMech::RSA_MD5_PKCS:
			type = NID_md5;
			break;
		case AsymMech::RSA_SHA1_PKCS:
			type = NID_sha1;
			break;
		case AsymMech::RSA_SHA224_PKCS:
			type = NID_sha224;
			break;
		case AsymMech::RSA_SHA256_PKCS:
			type = NID_sha256;
			break;
		case AsymMech::RSA_SHA384_PKCS:
			type = NID_sha384;
			break;
		case AsymMech::RSA_SHA512_PKCS:
			type = NID_sha512;
			break;
		case AsymMech::RSA_SHA1_PKCS_PSS:
			isPSS = true;
			hash = EVP_sha1();
			break;
		case AsymMech::RSA_SHA224_PKCS_PSS:
			isPSS = true;
			hash = EVP_sha224();
			break;
		case AsymMech::RSA_SHA256_PKCS_PSS:
			isPSS = true;
			hash = EVP_sha256();
			break;
		case AsymMech::RSA_SHA384_PKCS_PSS:
			isPSS = true;
			hash = EVP_sha384();
			break;
		case AsymMech::RSA_SHA512_PKCS_PSS:
			isPSS = true;
			hash = EVP_sha512();
			break;
		case AsymMech::RSA_SSL:
			type = NID_md5_sha1;
			break;
		default:
			break;
	}

	// Perform the verify operation
	bool rv;

	if (isPSS)
	{
		ByteString plain;
		plain.resize(pk->getN().size());
		int result = RSA_public_decrypt(signature.size(),
						(unsigned char*) signature.const_byte_str(),
						&plain[0],
						pk->getOSSLKey(),
						RSA_NO_PADDING);
		if (result < 0)
		{
			rv = false;
			ERROR_MSG("RSA public decrypt failed (0x%08X)", ERR_get_error());
		}
		else
		{
			plain.resize(result);
			result = RSA_verify_PKCS1_PSS(pk->getOSSLKey(), &digest[0],
						      hash, &plain[0], sLen);
			if (result == 1)
			{
				rv = true;
			}
			else
			{
				rv = false;
				ERROR_MSG("RSA PSS verify failed (0x%08X)", ERR_get_error());
			}
		}
	}
	else
	{
		rv = (RSA_verify(type, &digest[0], digest.size(), (unsigned char*) signature.const_byte_str(), signature.size(), pk->getOSSLKey()) == 1);

		if (!rv) ERROR_MSG("RSA verify failed (0x%08X)", ERR_get_error());
	}

	return rv;
}
Ejemplo n.º 2
0
int
KA_CTX_set_protocol(KA_CTX *ctx, int protocol)
{
    if (!ctx) {
        log_err("Invalid arguments");
        return 0;
    }

    if (       protocol == NID_id_CA_DH_3DES_CBC_CBC
            || protocol == NID_id_PACE_DH_GM_3DES_CBC_CBC
            || protocol == NID_id_PACE_DH_IM_3DES_CBC_CBC) {
        ctx->generate_key = dh_generate_key;
        ctx->compute_key = dh_compute_key;
        ctx->mac_keylen = 16;
        ctx->md = EVP_sha1();
        ctx->cipher = EVP_des_ede_cbc();
        ctx->enc_keylen = ctx->cipher->key_len;

    } else if (protocol == NID_id_CA_DH_AES_CBC_CMAC_128
            || protocol == NID_id_PACE_DH_GM_AES_CBC_CMAC_128
            || protocol == NID_id_PACE_DH_IM_AES_CBC_CMAC_128) {
        ctx->generate_key = dh_generate_key;
        ctx->compute_key = dh_compute_key;
        ctx->mac_keylen = 16;
        ctx->cmac_ctx = NULL; /* We don't set cmac_ctx, because of potential segfaults */
        ctx->md = EVP_sha1();
        ctx->cipher = EVP_aes_128_cbc();
        ctx->enc_keylen = ctx->cipher->key_len;

    } else if (protocol == NID_id_CA_DH_AES_CBC_CMAC_192
            || protocol == NID_id_PACE_DH_GM_AES_CBC_CMAC_192
            || protocol == NID_id_PACE_DH_IM_AES_CBC_CMAC_192) {
        ctx->generate_key = dh_generate_key;
        ctx->compute_key = dh_compute_key;
        ctx->mac_keylen = 24;
        ctx->cmac_ctx = NULL; /* We don't set cmac_ctx, because of potential segfaults */
        ctx->md = EVP_sha256();
        ctx->cipher = EVP_aes_192_cbc();
        ctx->enc_keylen = ctx->cipher->key_len;

    } else if (protocol == NID_id_CA_DH_AES_CBC_CMAC_256
            || protocol == NID_id_PACE_DH_GM_AES_CBC_CMAC_256
            || protocol == NID_id_PACE_DH_IM_AES_CBC_CMAC_256) {
        ctx->generate_key = dh_generate_key;
        ctx->compute_key = dh_compute_key;
        ctx->mac_keylen = 32;
        ctx->cmac_ctx = NULL; /* We don't set cmac_ctx, because of potential segfaults */
        ctx->md = EVP_sha256();
        ctx->cipher = EVP_aes_256_cbc();
        ctx->enc_keylen = ctx->cipher->key_len;

    } else if (protocol == NID_id_CA_ECDH_3DES_CBC_CBC
            || protocol == NID_id_PACE_ECDH_GM_3DES_CBC_CBC
            || protocol == NID_id_PACE_ECDH_IM_3DES_CBC_CBC) {
        ctx->generate_key = ecdh_generate_key;
        ctx->compute_key = ecdh_compute_key;
        ctx->mac_keylen = 16;
        ctx->md = EVP_sha1();
        ctx->cipher = EVP_des_ede_cbc();
        ctx->enc_keylen = ctx->cipher->key_len;

    } else if (protocol == NID_id_CA_ECDH_AES_CBC_CMAC_128
            || protocol == NID_id_PACE_ECDH_GM_AES_CBC_CMAC_128
            || protocol == NID_id_PACE_ECDH_IM_AES_CBC_CMAC_128) {
        ctx->generate_key = ecdh_generate_key;
        ctx->compute_key = ecdh_compute_key;
        ctx->mac_keylen = 16;
        ctx->cmac_ctx = NULL; /* We don't set cmac_ctx, because of potential segfaults */
        ctx->md = EVP_sha1();
        ctx->cipher = EVP_aes_128_cbc();
        ctx->enc_keylen = ctx->cipher->key_len;

    } else if (protocol == NID_id_CA_ECDH_AES_CBC_CMAC_192
            || protocol == NID_id_PACE_ECDH_GM_AES_CBC_CMAC_192
            || protocol == NID_id_PACE_ECDH_IM_AES_CBC_CMAC_192) {
        ctx->generate_key = ecdh_generate_key;
        ctx->compute_key = ecdh_compute_key;
        ctx->mac_keylen = 24;
        ctx->cmac_ctx = NULL; /* We don't set cmac_ctx, because of potential segfaults */
        ctx->md = EVP_sha256();
        ctx->cipher = EVP_aes_192_cbc();
        ctx->enc_keylen = ctx->cipher->key_len;

    } else if (protocol == NID_id_CA_ECDH_AES_CBC_CMAC_256
            || protocol == NID_id_PACE_ECDH_GM_AES_CBC_CMAC_256
            || protocol == NID_id_PACE_ECDH_IM_AES_CBC_CMAC_256) {
        ctx->generate_key = ecdh_generate_key;
        ctx->compute_key = ecdh_compute_key;
        ctx->mac_keylen = 32;
        ctx->cmac_ctx = NULL; /* We don't set cmac_ctx, because of potential segfaults */
        ctx->md = EVP_sha256();
        ctx->cipher = EVP_aes_256_cbc();
        ctx->enc_keylen = ctx->cipher->key_len;

    } else {
        log_err("Unknown protocol");
        return 0;
    }

    return 1;
}
Ejemplo n.º 3
0
int SSL_library_init(void)
	{

#ifndef OPENSSL_NO_DES
	EVP_add_cipher(EVP_des_cbc());
	EVP_add_cipher(EVP_des_ede3_cbc());
#endif
#ifndef OPENSSL_NO_IDEA
	EVP_add_cipher(EVP_idea_cbc());
#endif
#ifndef OPENSSL_NO_RC4
	EVP_add_cipher(EVP_rc4());
#if !defined(OPENSSL_NO_MD5) && (defined(__x86_64) || defined(__x86_64__))
	EVP_add_cipher(EVP_rc4_hmac_md5());
#endif
#endif  
#ifndef OPENSSL_NO_RC2
	EVP_add_cipher(EVP_rc2_cbc());
	/* Not actually used for SSL/TLS but this makes PKCS#12 work
	 * if an application only calls SSL_library_init().
	 */
	EVP_add_cipher(EVP_rc2_40_cbc());
#endif
#ifndef OPENSSL_NO_AES
	EVP_add_cipher(EVP_aes_128_cbc());
	EVP_add_cipher(EVP_aes_192_cbc());
	EVP_add_cipher(EVP_aes_256_cbc());
	EVP_add_cipher(EVP_aes_128_gcm());
	EVP_add_cipher(EVP_aes_256_gcm());
#if !defined(OPENSSL_NO_SHA) && !defined(OPENSSL_NO_SHA1)
	EVP_add_cipher(EVP_aes_128_cbc_hmac_sha1());
	EVP_add_cipher(EVP_aes_256_cbc_hmac_sha1());
#endif

#endif
#ifndef OPENSSL_NO_CAMELLIA
	EVP_add_cipher(EVP_camellia_128_cbc());
	EVP_add_cipher(EVP_camellia_256_cbc());
#endif

#ifndef OPENSSL_NO_SEED
	EVP_add_cipher(EVP_seed_cbc());
#endif
  
#ifndef OPENSSL_NO_MD5
	EVP_add_digest(EVP_md5());
	EVP_add_digest_alias(SN_md5,"ssl2-md5");
	EVP_add_digest_alias(SN_md5,"ssl3-md5");
#endif
#ifndef OPENSSL_NO_SHA
	EVP_add_digest(EVP_sha1()); /* RSA with sha1 */
	EVP_add_digest_alias(SN_sha1,"ssl3-sha1");
	EVP_add_digest_alias(SN_sha1WithRSAEncryption,SN_sha1WithRSA);
#endif
#ifndef OPENSSL_NO_SHA256
	EVP_add_digest(EVP_sha224());
	EVP_add_digest(EVP_sha256());
#endif
#ifndef OPENSSL_NO_SHA512
	EVP_add_digest(EVP_sha384());
	EVP_add_digest(EVP_sha512());
#endif
#if !defined(OPENSSL_NO_SHA) && !defined(OPENSSL_NO_DSA)
	EVP_add_digest(EVP_dss1()); /* DSA with sha1 */
	EVP_add_digest_alias(SN_dsaWithSHA1,SN_dsaWithSHA1_2);
	EVP_add_digest_alias(SN_dsaWithSHA1,"DSS1");
	EVP_add_digest_alias(SN_dsaWithSHA1,"dss1");
#endif
#ifndef OPENSSL_NO_ECDSA
	EVP_add_digest(EVP_ecdsa());
#endif
	/* If you want support for phased out ciphers, add the following */
#if 0
	EVP_add_digest(EVP_sha());
	EVP_add_digest(EVP_dss());
#endif
#ifndef OPENSSL_NO_COMP
	/* This will initialise the built-in compression algorithms.
	   The value returned is a STACK_OF(SSL_COMP), but that can
	   be discarded safely */
	(void)SSL_COMP_get_compression_methods();
#endif
	/* initialize cipher/digest methods table */
	ssl_load_ciphers();
	return(1);
	}
Ejemplo n.º 4
0
/* DTLS-SRTP initialization */
gint janus_dtls_srtp_init(gchar *server_pem, gchar *server_key) {
	ssl_ctx = SSL_CTX_new(DTLSv1_method());
	if(!ssl_ctx) {
		JANUS_LOG(LOG_FATAL, "Ops, error creating DTLS context?\n");
		return -1;
	}
	SSL_CTX_set_verify(ssl_ctx, SSL_VERIFY_PEER | SSL_VERIFY_FAIL_IF_NO_PEER_CERT, janus_dtls_verify_callback);
	SSL_CTX_set_tlsext_use_srtp(ssl_ctx, "SRTP_AES128_CM_SHA1_80");	/* FIXME Should we support something else as well? */
	if(!server_pem || !SSL_CTX_use_certificate_file(ssl_ctx, server_pem, SSL_FILETYPE_PEM)) {
		JANUS_LOG(LOG_FATAL, "Certificate error, does it exist?\n");
		JANUS_LOG(LOG_FATAL, "  %s\n", server_pem);
		return -2;
	}
	if(!server_key || !SSL_CTX_use_PrivateKey_file(ssl_ctx, server_key, SSL_FILETYPE_PEM)) {
		JANUS_LOG(LOG_FATAL, "Certificate key error, does it exist?\n");
		JANUS_LOG(LOG_FATAL, "  %s\n", server_key);
		return -3;
	}
	if(!SSL_CTX_check_private_key(ssl_ctx)) {
		JANUS_LOG(LOG_FATAL, "Certificate check error...\n");
		return -4;
	}
	BIO *certbio = BIO_new(BIO_s_file());
	if(certbio == NULL) {
		JANUS_LOG(LOG_FATAL, "Certificate BIO error...\n");
		return -5;
	}
	if(BIO_read_filename(certbio, server_pem) == 0) {
		JANUS_LOG(LOG_FATAL, "Error reading certificate...\n");
		BIO_free_all(certbio);
		return -6;
	}
	X509 *cert = PEM_read_bio_X509(certbio, NULL, 0, NULL);
	if(cert == NULL) {
		JANUS_LOG(LOG_FATAL, "Error reading certificate...\n");
		BIO_free_all(certbio);
		return -7;
	}
	unsigned int size;
	unsigned char fingerprint[EVP_MAX_MD_SIZE];
	if(X509_digest(cert, EVP_sha256(), (unsigned char *)fingerprint, &size) == 0) {
		JANUS_LOG(LOG_FATAL, "Error converting X509 structure...\n");
		X509_free(cert);
		BIO_free_all(certbio);
		return -7;
	}
	char *lfp = (char *)&local_fingerprint;
	int i = 0;
	for(i = 0; i < size; i++) {
		sprintf(lfp, "%.2X:", fingerprint[i]);
		lfp += 3;
	}
	*(lfp-1) = 0;
	JANUS_LOG(LOG_INFO, "Fingerprint of our certificate: %s\n", local_fingerprint);
	X509_free(cert);
	BIO_free_all(certbio);
	SSL_CTX_set_cipher_list(ssl_ctx, DTLS_CIPHERS);

	/* Initialize libsrtp */
	if(srtp_init() != err_status_ok) {
		JANUS_LOG(LOG_FATAL, "Ops, error setting up libsrtp?\n");
		return 5;
	}
	return 0;
}
Ejemplo n.º 5
0
int main(int argc, char *argv[])
{
# ifndef OPENSSL_NO_MD5
    int i;
    char *p;
# endif
    int err = 0;
    HMAC_CTX ctx, ctx2;
    unsigned char buf[EVP_MAX_MD_SIZE];
    unsigned int len;

# ifdef OPENSSL_NO_MD5
    printf("test skipped: MD5 disabled\n");
# else

#  ifdef CHARSET_EBCDIC
    ebcdic2ascii(test[0].data, test[0].data, test[0].data_len);
    ebcdic2ascii(test[1].data, test[1].data, test[1].data_len);
    ebcdic2ascii(test[2].key, test[2].key, test[2].key_len);
    ebcdic2ascii(test[2].data, test[2].data, test[2].data_len);
#  endif

    for (i = 0; i < 4; i++) {
        p = pt(HMAC(EVP_md5(),
                    test[i].key, test[i].key_len,
                    test[i].data, test[i].data_len, NULL, NULL),
                    MD5_DIGEST_LENGTH);

        if (strcmp(p, (const char *)test[i].digest) != 0) {
            printf("Error calculating HMAC on %d entry'\n", i);
            printf("got %s instead of %s\n", p, test[i].digest);
            err++;
        } else
            printf("test %d ok\n", i);
    }
# endif                         /* OPENSSL_NO_MD5 */

/* test4 */
    HMAC_CTX_init(&ctx);
    if (HMAC_Init_ex(&ctx, NULL, 0, NULL, NULL)) {
        printf("Should fail to initialise HMAC with empty MD and key (test 4)\n");
        err++;
        goto test5;
    }
    if (HMAC_Update(&ctx, test[4].data, test[4].data_len)) {
        printf("Should fail HMAC_Update with ctx not set up (test 4)\n");
        err++;
        goto test5;
    }
    if (HMAC_Init_ex(&ctx, NULL, 0, EVP_sha1(), NULL)) {
        printf("Should fail to initialise HMAC with empty key (test 4)\n");
        err++;
        goto test5;
    }
    if (HMAC_Update(&ctx, test[4].data, test[4].data_len)) {
        printf("Should fail HMAC_Update with ctx not set up (test 4)\n");
        err++;
        goto test5;
    }
    printf("test 4 ok\n");
test5:
    HMAC_CTX_cleanup(&ctx);
    HMAC_CTX_init(&ctx);
    if (HMAC_Init_ex(&ctx, test[4].key, test[4].key_len, NULL, NULL)) {
        printf("Should fail to initialise HMAC with empty MD (test 5)\n");
        err++;
        goto test6;
    }
    if (HMAC_Update(&ctx, test[4].data, test[4].data_len)) {
        printf("Should fail HMAC_Update with ctx not set up (test 5)\n");
        err++;
        goto test6;
    }
    if (HMAC_Init_ex(&ctx, test[4].key, -1, EVP_sha1(), NULL)) {
        printf("Should fail to initialise HMAC with invalid key len(test 5)\n");
        err++;
        goto test6;
    }
    if (!HMAC_Init_ex(&ctx, test[4].key, test[4].key_len, EVP_sha1(), NULL)) {
        printf("Failed to initialise HMAC (test 5)\n");
        err++;
        goto test6;
    }
    if (!HMAC_Update(&ctx, test[4].data, test[4].data_len)) {
        printf("Error updating HMAC with data (test 5)\n");
        err++;
        goto test6;
    }
    if (!HMAC_Final(&ctx, buf, &len)) {
        printf("Error finalising data (test 5)\n");
        err++;
        goto test6;
    }
    p = pt(buf, len);
    if (strcmp(p, (const char *)test[4].digest) != 0) {
        printf("Error calculating interim HMAC on test 5\n");
        printf("got %s instead of %s\n", p, test[4].digest);
        err++;
        goto test6;
    }
    if (HMAC_Init_ex(&ctx, NULL, 0, EVP_sha256(), NULL)) {
        printf("Should disallow changing MD without a new key (test 5)\n");
        err++;
        goto test6;
    }
    if (!HMAC_Init_ex(&ctx, test[4].key, test[4].key_len, EVP_sha256(), NULL)) {
        printf("Failed to reinitialise HMAC (test 5)\n");
        err++;
        goto test6;
    }
    if (!HMAC_Update(&ctx, test[5].data, test[5].data_len)) {
        printf("Error updating HMAC with data (sha256) (test 5)\n");
        err++;
        goto test6;
    }
    if (!HMAC_Final(&ctx, buf, &len)) {
        printf("Error finalising data (sha256) (test 5)\n");
        err++;
        goto test6;
    }
    p = pt(buf, len);
    if (strcmp(p, (const char *)test[5].digest) != 0) {
        printf("Error calculating 2nd interim HMAC on test 5\n");
        printf("got %s instead of %s\n", p, test[5].digest);
        err++;
        goto test6;
    }
    if (!HMAC_Init_ex(&ctx, test[6].key, test[6].key_len, NULL, NULL)) {
        printf("Failed to reinitialise HMAC with key (test 5)\n");
        err++;
        goto test6;
    }
    if (!HMAC_Update(&ctx, test[6].data, test[6].data_len)) {
        printf("Error updating HMAC with data (new key) (test 5)\n");
        err++;
        goto test6;
    }
    if (!HMAC_Final(&ctx, buf, &len)) {
        printf("Error finalising data (new key) (test 5)\n");
        err++;
        goto test6;
    }
    p = pt(buf, len);
    if (strcmp(p, (const char *)test[6].digest) != 0) {
        printf("error calculating HMAC on test 5\n");
        printf("got %s instead of %s\n", p, test[6].digest);
        err++;
    } else {
        printf("test 5 ok\n");
    }
test6:
    HMAC_CTX_cleanup(&ctx);
    HMAC_CTX_init(&ctx);
    if (!HMAC_Init_ex(&ctx, test[7].key, test[7].key_len, EVP_sha1(), NULL)) {
        printf("Failed to initialise HMAC (test 6)\n");
        err++;
        goto end;
    }
    if (!HMAC_Update(&ctx, test[7].data, test[7].data_len)) {
        printf("Error updating HMAC with data (test 6)\n");
        err++;
        goto end;
    }
    if (!HMAC_CTX_copy(&ctx2, &ctx)) {
        printf("Failed to copy HMAC_CTX (test 6)\n");
        err++;
        goto end;
    }
    if (!HMAC_Final(&ctx2, buf, &len)) {
        printf("Error finalising data (test 6)\n");
        err++;
        goto end;
    }
    p = pt(buf, len);
    if (strcmp(p, (const char *)test[7].digest) != 0) {
        printf("Error calculating HMAC on test 6\n");
        printf("got %s instead of %s\n", p, test[7].digest);
        err++;
    } else {
        printf("test 6 ok\n");
    }
end:
    HMAC_CTX_cleanup(&ctx);
    EXIT(err);
    return (0);
}
Ejemplo n.º 6
0
static int knot_tsig_compute_digest(const uint8_t *wire, size_t wire_len,
                                    uint8_t *digest, size_t *digest_len,
                                    const knot_tsig_key_t *key)
{
	if (!wire || !digest || !digest_len || !key) {
		dbg_tsig("TSIG: digest: bad args.\n");
		return KNOT_EINVAL;
	}

	if (!key->name) {
		dbg_tsig("TSIG: digest: no algorithm\n");
		return KNOT_EMALF;
	}

	knot_tsig_algorithm_t tsig_alg = key->algorithm;
	if (tsig_alg == 0) {
		dbg_tsig("TSIG: digest: unknown algorithm\n");
		return KNOT_TSIG_EBADSIG;
	}

	dbg_tsig_detail("TSIG: key size: %zu\n", key->secret.size);
	dbg_tsig_detail("TSIG: key:\n");
	dbg_tsig_hex_detail((char *)key->secret.data, key->secret.size);
	dbg_tsig_detail("Wire for signing is %zu bytes long.\n", wire_len);

	/* Compute digest. */
	HMAC_CTX ctx;

	switch (tsig_alg) {
		case KNOT_TSIG_ALG_HMAC_MD5:
			HMAC_Init(&ctx, key->secret.data,
			          key->secret.size, EVP_md5());
			break;
		case KNOT_TSIG_ALG_HMAC_SHA1:
			HMAC_Init(&ctx, key->secret.data,
			          key->secret.size, EVP_sha1());
			break;
		case KNOT_TSIG_ALG_HMAC_SHA224:
			HMAC_Init(&ctx, key->secret.data,
			          key->secret.size, EVP_sha224());
			break;
		case KNOT_TSIG_ALG_HMAC_SHA256:
			HMAC_Init(&ctx, key->secret.data,
			          key->secret.size, EVP_sha256());
			break;
		case KNOT_TSIG_ALG_HMAC_SHA384:
			HMAC_Init(&ctx, key->secret.data,
			          key->secret.size, EVP_sha384());
			break;
		case KNOT_TSIG_ALG_HMAC_SHA512:
			HMAC_Init(&ctx, key->secret.data,
			          key->secret.size, EVP_sha512());
			break;
		default:
			return KNOT_ENOTSUP;
	} /* switch */

	unsigned tmp_dig_len = *digest_len;
	HMAC_Update(&ctx, (const unsigned char *)wire, wire_len);
	HMAC_Final(&ctx, digest, &tmp_dig_len);
	*digest_len = tmp_dig_len;

	HMAC_CTX_cleanup(&ctx);

	return KNOT_EOK;
}
Ejemplo n.º 7
0
int main(int argc, char * const argv[]) {
	int ret = EX_DATAERR;
	ssize_t cd_len, reg_len;
	unsigned char kh_len;
	unsigned const char *kh, *sig;
	size_t siglen;
	EVP_PKEY *pkey = NULL;
	unsigned char cp_hash[SHA256_DIGEST_LENGTH];
	unsigned char ap_hash[SHA256_DIGEST_LENGTH];
	EVP_MD_CTX ctx;
	X509 *crt = NULL;
	unsigned const char *ptr;
	int i;

	cd_len = strlen(clientData);
	reg_len = sizeof(registrationData);

	if (registrationData[0] != 0x05) {
		fprintf(stderr, "invalid header byte\n");
		goto DONE;
	}

	/* key handle */
	kh = registrationData+67;
	kh_len = registrationData[66];

	/* parse attestation certificate (X.509) */
	ptr = registrationData + 67 + kh_len;
	crt = d2i_X509(NULL, (const unsigned char**)&ptr, reg_len - (ptr-registrationData));
	if (crt == NULL) {
		fprintf(stderr, "Error while parsing X509\n");
		goto DONE;
	}

	/* check if this is a valid signature */
	sig = ptr;
	ECDSA_SIG *ecsig = d2i_ECDSA_SIG(NULL, (const unsigned char**)&ptr, reg_len - (ptr-registrationData));
	if (ecsig == NULL) {
		fprintf(stderr, "Error while reading signature\n");
		ECDSA_SIG_free(ecsig);
		ecsig = NULL;
		goto DONE;
	}
	siglen = ptr-sig;
	ECDSA_SIG_free(ecsig);
	ecsig = NULL;

	/* extract public key from X509 attestation certificare */
	pkey = X509_get_pubkey(crt);
	if (pkey == NULL) {
		fprintf(stderr, "Can't get public key!\n");
		goto DONE;
	}

	/* generate SHA256 hash on challenge parameter and application parameter */
	(void)SHA256((const unsigned char*)clientData, cd_len, cp_hash);
	(void)SHA256((const unsigned char*)appId, strlen(appId), ap_hash);

	/* verify signature */
	if (EVP_VerifyInit(&ctx, EVP_sha256()) != 1) {
		fprintf(stderr, "EVP_VerifyInit() failed\n");
		goto DONE;
	}

	(void)EVP_VerifyUpdate(&ctx, "\0", 1UL);
	(void)EVP_VerifyUpdate(&ctx, ap_hash, 32UL);
	(void)EVP_VerifyUpdate(&ctx, cp_hash, 32UL);
	(void)EVP_VerifyUpdate(&ctx, kh, (unsigned long)kh_len);
	(void)EVP_VerifyUpdate(&ctx, registrationData+1, 65UL);

	if ((i = EVP_VerifyFinal(&ctx, sig, siglen, pkey)) != 1) {
		fprintf(stderr, "EVP_VerifyFinal failed: err=%i, %s\n", i, ERR_error_string(ERR_get_error(), NULL));
		(void)EVP_MD_CTX_cleanup(&ctx);
		goto DONE;
	}

	(void)EVP_MD_CTX_cleanup(&ctx);


	printf("Valid response.\n");
	ret = EX_OK;

DONE:

	if (crt != NULL) {
		X509_free(crt);
		crt = NULL;
	}

	if (pkey != NULL) {
		EVP_PKEY_free(pkey);
		pkey = NULL;
	}

	return(ret);
}
Ejemplo n.º 8
0
static int pbkdf2_check(
	const struct berval *scheme,
	const struct berval *passwd,
	const struct berval *cred,
	const char **text)
{
	int rc;
	int iteration;

	/* salt_value require PBKDF2_SALT_SIZE + 1 in lutil_b64_pton. */
	unsigned char salt_value[PBKDF2_SALT_SIZE + 1];
	char salt_b64[LUTIL_BASE64_ENCODE_LEN(PBKDF2_SALT_SIZE) + 1];
	/* dk_value require PBKDF2_MAX_DK_SIZE + 1 in lutil_b64_pton. */
	unsigned char dk_value[PBKDF2_MAX_DK_SIZE + 1];
	char dk_b64[LUTIL_BASE64_ENCODE_LEN(PBKDF2_MAX_DK_SIZE) + 1];
	unsigned char input_dk_value[PBKDF2_MAX_DK_SIZE];
	size_t dk_len;
#ifdef HAVE_OPENSSL
	const EVP_MD *md;
#elif HAVE_GNUTLS
	struct hmac_sha1_ctx sha1_ctx;
	struct hmac_sha256_ctx sha256_ctx;
	struct hmac_sha512_ctx sha512_ctx;
	void * current_ctx = NULL;
	pbkdf2_hmac_update current_hmac_update = NULL;
	pbkdf2_hmac_digest current_hmac_digest = NULL;
#endif

#ifdef SLAPD_PBKDF2_DEBUG
	printf("Checking for %s\n", scheme->bv_val);
	printf("  Stored Value:\t%s\n", passwd->bv_val);
	printf("  Input Cred:\t%s\n", cred->bv_val);
#endif

#ifdef HAVE_OPENSSL
	if(!ber_bvcmp(scheme, &pbkdf2_scheme)){
		dk_len = PBKDF2_SHA1_DK_SIZE;
		md = EVP_sha1();
	}else if(!ber_bvcmp(scheme, &pbkdf2_sha1_scheme)){
		dk_len = PBKDF2_SHA1_DK_SIZE;
		md = EVP_sha1();
	}else if(!ber_bvcmp(scheme, &pbkdf2_sha256_scheme)){
		dk_len = PBKDF2_SHA256_DK_SIZE;
		md = EVP_sha256();
	}else if(!ber_bvcmp(scheme, &pbkdf2_sha512_scheme)){
		dk_len = PBKDF2_SHA512_DK_SIZE;
		md = EVP_sha512();
	}else{
		return LUTIL_PASSWD_ERR;
	}
#elif HAVE_GNUTLS
	if(!ber_bvcmp(scheme, &pbkdf2_scheme)){
		dk_len = PBKDF2_SHA1_DK_SIZE;
		current_ctx = &sha1_ctx;
		current_hmac_update = (pbkdf2_hmac_update) &hmac_sha1_update;
		current_hmac_digest = (pbkdf2_hmac_digest) &hmac_sha1_digest;
		hmac_sha1_set_key(current_ctx, cred->bv_len, (const uint8_t *) cred->bv_val);
	}else if(!ber_bvcmp(scheme, &pbkdf2_sha1_scheme)){
		dk_len = PBKDF2_SHA1_DK_SIZE;
		current_ctx = &sha1_ctx;
		current_hmac_update = (pbkdf2_hmac_update) &hmac_sha1_update;
		current_hmac_digest = (pbkdf2_hmac_digest) &hmac_sha1_digest;
		hmac_sha1_set_key(current_ctx, cred->bv_len, (const uint8_t *) cred->bv_val);
	}else if(!ber_bvcmp(scheme, &pbkdf2_sha256_scheme)){
		dk_len = PBKDF2_SHA256_DK_SIZE;
		current_ctx = &sha256_ctx;
		current_hmac_update = (pbkdf2_hmac_update) &hmac_sha256_update;
		current_hmac_digest = (pbkdf2_hmac_digest) &hmac_sha256_digest;
		hmac_sha256_set_key(current_ctx, cred->bv_len, (const uint8_t *) cred->bv_val);
	}else if(!ber_bvcmp(scheme, &pbkdf2_sha512_scheme)){
		dk_len = PBKDF2_SHA512_DK_SIZE;
		current_ctx = &sha512_ctx;
		current_hmac_update = (pbkdf2_hmac_update) &hmac_sha512_update;
		current_hmac_digest = (pbkdf2_hmac_digest) &hmac_sha512_digest;
		hmac_sha512_set_key(current_ctx, cred->bv_len, (const uint8_t *) cred->bv_val);
	}else{
		return LUTIL_PASSWD_ERR;
	}
#endif

	iteration = atoi(passwd->bv_val);
	if(iteration < 1){
		return LUTIL_PASSWD_ERR;
	}

	char *ptr;
	ptr = strchr(passwd->bv_val, '$');
	if(!ptr){
		return LUTIL_PASSWD_ERR;
	}
	ptr++; /* skip '$' */
	rc = ab64_to_b64(ptr, salt_b64, sizeof(salt_b64));
	if(rc < 0){
		return LUTIL_PASSWD_ERR;
	}

	ptr = strchr(ptr, '$');
	if(!ptr){
		return LUTIL_PASSWD_ERR;
	}
	ptr++; /* skip '$' */
	rc = ab64_to_b64(ptr, dk_b64, sizeof(dk_b64));
	if(rc < 0){
		return LUTIL_PASSWD_ERR;
	}

	/* The targetsize require PBKDF2_SALT_SIZE + 1 in lutil_b64_pton. */
	rc = lutil_b64_pton(salt_b64, salt_value, PBKDF2_SALT_SIZE + 1);
	if(rc < 0){
		return LUTIL_PASSWD_ERR;
	}

	/* consistency check */
	if(rc != PBKDF2_SALT_SIZE){
		return LUTIL_PASSWD_ERR;
	}

	/* The targetsize require PBKDF2_MAX_DK_SIZE + 1 in lutil_b64_pton. */
	rc = lutil_b64_pton(dk_b64, dk_value, sizeof(dk_value));
	if(rc < 0){
		return LUTIL_PASSWD_ERR;
	}

	/* consistency check */
	if(rc != dk_len){
		return LUTIL_PASSWD_ERR;
	}

#ifdef HAVE_OPENSSL
	if(!PKCS5_PBKDF2_HMAC(cred->bv_val, cred->bv_len,
						  salt_value, PBKDF2_SALT_SIZE,
						  iteration, md, dk_len, input_dk_value)){
		return LUTIL_PASSWD_ERR;
	}
#elif HAVE_GNUTLS
	PBKDF2(current_ctx, current_hmac_update, current_hmac_digest,
						  dk_len, iteration,
						  PBKDF2_SALT_SIZE, salt_value,
						  dk_len, input_dk_value);
#endif

	rc = memcmp(dk_value, input_dk_value, dk_len);
#ifdef SLAPD_PBKDF2_DEBUG
	printf("  Iteration:\t%d\n", iteration);
	printf("  Base64 Salt:\t%s\n", salt_b64);
	printf("  Base64 DK:\t%s\n", dk_b64);
	int i;
	printf("  Stored Salt:\t");
	for(i=0; i<PBKDF2_SALT_SIZE; i++){
		printf("%02x", salt_value[i]);
	}
	printf("\n");

	printf("  Stored DK:\t");
	for(i=0; i<dk_len; i++){
		printf("%02x", dk_value[i]);
	}
	printf("\n");

	printf("  Input DK:\t");
	for(i=0; i<dk_len; i++){
		printf("%02x", input_dk_value[i]);
	}
	printf("\n");
	printf("  Result:\t%d\n", rc);
#endif
	return rc?LUTIL_PASSWD_ERR:LUTIL_PASSWD_OK;
}
Ejemplo n.º 9
0
Archivo: vpn.c Proyecto: BradleyZhu/VPN
int main(int argc, char *argv[])
{
/*
//test
char testki[32];
print(testki,32);
menuOp(testki);
print(testki,32);
menuOp(testki);
print(testki,32);
*/

//select mode from argv, and decide the port and ip and if client or server
	int port, PORT;
	char c, *p, *ip;
	int MODE = 0, TUNMODE = IFF_TUN, DEBUG = 0;
	while ((c = getopt(argc, argv, "s:c:ehd")) != -1) {
		switch (c) {
		case 'h':
			usage();
		case 'd':
			DEBUG++;
			break;
		case 's':
			MODE = 1;
			PORT = atoi(optarg);
			break;
		case 'c':
			MODE = 2;
			p = memchr(optarg,':',16);
			if (!p) ERROR("invalid argument : [%s]\n",optarg);
			*p = 0;
			ip = optarg;
			port = atoi(p+1);
			PORT = 0;
			break;
		case 'e':
			TUNMODE = IFF_TAP;
			break;
		default:
			usage();
		}
	}
	if (MODE == 0) usage();

///////////////////////////tunnel communicate part begin////////////////////////////////////
	struct sockaddr_in sin, sout, from;
	struct ifreq ifr;
	int fd, s, fromlen, soutlen, l, outl;
	
	/* Allow enough space in output buffer for additional block */
	unsigned char buf[BUFFER_LENGTH + OUTPUT_LENGTH], encryptedbuf[BUFFER_LENGTH + OUTPUT_LENGTH + EVP_MAX_BLOCK_LENGTH];
	unsigned char digest[OUTPUT_LENGTH];
	fd_set fdset;

	if ( (fd = open("/dev/net/tun",O_RDWR)) < 0) PERROR("open");
	memset(&ifr, 0, sizeof(ifr));
	ifr.ifr_flags = TUNMODE;
	strncpy(ifr.ifr_name, "toto%d", IFNAMSIZ);
	if (ioctl(fd, TUNSETIFF, (void *)&ifr) < 0) PERROR("ioctl");
	printf("Allocated interface %s. Configure and use it\n", ifr.ifr_name);
	
	s = socket(PF_INET, SOCK_DGRAM, 0);
	sin.sin_family = AF_INET;
	sin.sin_addr.s_addr = htonl(INADDR_ANY);
	sin.sin_port = htons(PORT);
	if ( bind(s,(struct sockaddr *)&sin, sizeof(sin)) < 0) PERROR("bind");

	fromlen = sizeof(from);

	if (MODE == 1) {
		while(1) {
			l = recvfrom(s, buf, sizeof(buf), 0, (struct sockaddr *)&from, &fromlen);
			if (l < 0) PERROR("recvfrom");
			if (strncmp(MAGIC_WORD, buf, sizeof(MAGIC_WORD)) == 0)
				break;
//			printf("Bad magic word from %s:%i\n", 
//			       inet_ntoa(from.sin_addr.s_addr), ntohs(from.sin_port));
		} 
		l = sendto(s, MAGIC_WORD, sizeof(MAGIC_WORD), 0, (struct sockaddr *)&from, fromlen);
		if (l < 0) PERROR("sendto");
	} else {
		from.sin_family = AF_INET;
		from.sin_port = htons(port);
		inet_aton(ip, &from.sin_addr);
		l =sendto(s, MAGIC_WORD, sizeof(MAGIC_WORD), 0, (struct sockaddr *)&from, sizeof(from));
		if (l < 0) PERROR("sendto");
		l = recvfrom(s,buf, sizeof(buf), 0, (struct sockaddr *)&from, &fromlen);
		if (l < 0) PERROR("recvfrom");
		if (strncmp(MAGIC_WORD, buf, sizeof(MAGIC_WORD) != 0))
			ERROR("Bad magic word for peer\n");
	}
///////////////////////////tunnel create part end////////////////////////////////////

char newkeyiv[32];
char keyiv[32];// = {1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 ,0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1};

//pipe and fork prepare
    int pipefd[2];
    pid_t cpid;

    if (pipe(pipefd) == -1) {
        perror("pipe");
        exit(EXIT_FAILURE);
    }
    cpid = fork();
    if (cpid == -1) {
        perror("fork");
        exit(EXIT_FAILURE);
    }

//pki part
    if (cpid > 0) {            // Parent writes argv[1] to pipe
        close(pipefd[0]);          // Close unused read end    

        //pki
	if(MODE == 1)
	{doPKIServer(cpid,pipefd,newkeyiv,port, PORT, ip);}
	else if(MODE == 2)
	{doPKIClient(cpid,pipefd,newkeyiv,port, PORT, ip);}

	//exit
        wait(NULL);                // Wait for child
	kill(cpid,SIGKILL);
    }

//tunnel part
    else {    // Child reads from pipe
        close(pipefd[1]);          // Close unused write end
	fcntl(pipefd[0],F_SETFL,O_NONBLOCK);//set unblock pipe read

///////////////////////////tunnel communicate part begin////////////////////////////////////
	int num;
        
	int i;
	char key[16];
		while (1) {
		num=read(pipefd[0], keyiv, 32);//read key and iv from pki process
		if(num==32){//if read new key and iv, print it
			printf("new key and iv:\n");
			print(keyiv,32);
		}
		FD_ZERO(&fdset);
		FD_SET(fd, &fdset);
		FD_SET(s, &fdset);
		if (select(fd+s+1, &fdset,NULL,NULL,NULL) < 0) PERROR("select");
		if (FD_ISSET(fd, &fdset)) {
			if (DEBUG) write(1,">", 1);
			l = read(fd, buf, BUFFER_LENGTH);
			if (l < 0) PERROR("read");
			// encrypt here
			do_crypt(keyiv, buf, l, encryptedbuf, &outl, 1);
			// hmac
for(i=0;i<16;i++)
{
	key[i] = keyiv[i];
}
			strncpy(digest, HMAC(EVP_sha256(), key, 16, (unsigned char *)encryptedbuf, outl, NULL, NULL), OUTPUT_LENGTH);
			// add on hmac
			strncpy(encryptedbuf + outl, digest, OUTPUT_LENGTH);
			outl += OUTPUT_LENGTH;
			if (sendto(s, encryptedbuf, outl, 0, (struct sockaddr *)&from, fromlen) < 0) PERROR("sendto");
		} else {
			if (DEBUG) write(1,"<", 1);
			l = recvfrom(s, encryptedbuf, sizeof(encryptedbuf), 0, (struct sockaddr *)&sout, &soutlen);
			// get hmac
			l -= OUTPUT_LENGTH;
			strncpy(digest, encryptedbuf + l, OUTPUT_LENGTH);
for(i=0;i<16;i++)
{
	key[i] = keyiv[i];
}
			if (strncmp(digest, HMAC(EVP_sha256(), key, 16, (unsigned char *)encryptedbuf, l, NULL, NULL), OUTPUT_LENGTH))
			{
				continue;
			}
			// decrypt here
			do_crypt(keyiv, encryptedbuf, l, buf, &outl, 0);
			if (write(fd, buf, outl) < 0) PERROR("write");
		}
	}
///////////////////////////tunnel communicate part end////////////////////////////////////

	//exit
        _exit(EXIT_SUCCESS);
    }
}
Ejemplo n.º 10
0
/**
 * Setup key and digest for verification. Adjust sig if necessary.
 *
 * @param algo: key algorithm
 * @param evp_key: EVP PKEY public key to create.
 * @param digest_type: digest type to use
 * @param key: key to setup for.
 * @param keylen: length of key.
 * @return false on failure.
 */
static int
setup_key_digest(int algo, EVP_PKEY** evp_key, const EVP_MD** digest_type, 
	unsigned char* key, size_t keylen)
{
	DSA* dsa;
	RSA* rsa;

	switch(algo) {
		case LDNS_DSA:
		case LDNS_DSA_NSEC3:
			*evp_key = EVP_PKEY_new();
			if(!*evp_key) {
				log_err("verify: malloc failure in crypto");
				return 0;
			}
			dsa = ldns_key_buf2dsa_raw(key, keylen);
			if(!dsa) {
				verbose(VERB_QUERY, "verify: "
					"ldns_key_buf2dsa_raw failed");
				return 0;
			}
			if(EVP_PKEY_assign_DSA(*evp_key, dsa) == 0) {
				verbose(VERB_QUERY, "verify: "
					"EVP_PKEY_assign_DSA failed");
				return 0;
			}
			*digest_type = EVP_dss1();

			break;
		case LDNS_RSASHA1:
		case LDNS_RSASHA1_NSEC3:
#if defined(HAVE_EVP_SHA256) && defined(USE_SHA2)
		case LDNS_RSASHA256:
#endif
#if defined(HAVE_EVP_SHA512) && defined(USE_SHA2)
		case LDNS_RSASHA512:
#endif
			*evp_key = EVP_PKEY_new();
			if(!*evp_key) {
				log_err("verify: malloc failure in crypto");
				return 0;
			}
			rsa = ldns_key_buf2rsa_raw(key, keylen);
			if(!rsa) {
				verbose(VERB_QUERY, "verify: "
					"ldns_key_buf2rsa_raw SHA failed");
				return 0;
			}
			if(EVP_PKEY_assign_RSA(*evp_key, rsa) == 0) {
				verbose(VERB_QUERY, "verify: "
					"EVP_PKEY_assign_RSA SHA failed");
				return 0;
			}

			/* select SHA version */
#if defined(HAVE_EVP_SHA256) && defined(USE_SHA2)
			if(algo == LDNS_RSASHA256)
				*digest_type = EVP_sha256();
			else
#endif
#if defined(HAVE_EVP_SHA512) && defined(USE_SHA2)
				if(algo == LDNS_RSASHA512)
				*digest_type = EVP_sha512();
			else
#endif
				*digest_type = EVP_sha1();

			break;
		case LDNS_RSAMD5:
			*evp_key = EVP_PKEY_new();
			if(!*evp_key) {
				log_err("verify: malloc failure in crypto");
				return 0;
			}
			rsa = ldns_key_buf2rsa_raw(key, keylen);
			if(!rsa) {
				verbose(VERB_QUERY, "verify: "
					"ldns_key_buf2rsa_raw MD5 failed");
				return 0;
			}
			if(EVP_PKEY_assign_RSA(*evp_key, rsa) == 0) {
				verbose(VERB_QUERY, "verify: "
					"EVP_PKEY_assign_RSA MD5 failed");
				return 0;
			}
			*digest_type = EVP_md5();

			break;
#ifdef USE_GOST
		case LDNS_ECC_GOST:
			*evp_key = ldns_gost2pkey_raw(key, keylen);
			if(!*evp_key) {
				verbose(VERB_QUERY, "verify: "
					"ldns_gost2pkey_raw failed");
				return 0;
			}
			*digest_type = EVP_get_digestbyname("md_gost94");
			if(!*digest_type) {
				verbose(VERB_QUERY, "verify: "
					"EVP_getdigest md_gost94 failed");
				return 0;
			}
			break;
#endif
#ifdef USE_ECDSA
		case LDNS_ECDSAP256SHA256:
			*evp_key = ldns_ecdsa2pkey_raw(key, keylen,
				LDNS_ECDSAP256SHA256);
			if(!*evp_key) {
				verbose(VERB_QUERY, "verify: "
					"ldns_ecdsa2pkey_raw failed");
				return 0;
			}
#ifdef USE_ECDSA_EVP_WORKAROUND
			/* openssl before 1.0.0 fixes RSA with the SHA256
			 * hash in EVP.  We create one for ecdsa_sha256 */
			{
				static int md_ecdsa_256_done = 0;
				static EVP_MD md;
				if(!md_ecdsa_256_done) {
					EVP_MD m = *EVP_sha256();
					md_ecdsa_256_done = 1;
					m.required_pkey_type[0] = (*evp_key)->type;
					m.verify = (void*)ECDSA_verify;
					md = m;
				}
				*digest_type = &md;
			}
#else
			*digest_type = EVP_sha256();
#endif
			break;
		case LDNS_ECDSAP384SHA384:
			*evp_key = ldns_ecdsa2pkey_raw(key, keylen,
				LDNS_ECDSAP384SHA384);
			if(!*evp_key) {
				verbose(VERB_QUERY, "verify: "
					"ldns_ecdsa2pkey_raw failed");
				return 0;
			}
#ifdef USE_ECDSA_EVP_WORKAROUND
			/* openssl before 1.0.0 fixes RSA with the SHA384
			 * hash in EVP.  We create one for ecdsa_sha384 */
			{
				static int md_ecdsa_384_done = 0;
				static EVP_MD md;
				if(!md_ecdsa_384_done) {
					EVP_MD m = *EVP_sha384();
					md_ecdsa_384_done = 1;
					m.required_pkey_type[0] = (*evp_key)->type;
					m.verify = (void*)ECDSA_verify;
					md = m;
				}
				*digest_type = &md;
			}
#else
			*digest_type = EVP_sha384();
#endif
			break;
#endif /* USE_ECDSA */
		default:
			verbose(VERB_QUERY, "verify: unknown algorithm %d", 
				algo);
			return 0;
	}
	return 1;
}
CK_RV PKCS11_Digest_OpenSSL::DigestInit(Cryptoki_Session_Context* pSessionCtx, CK_MECHANISM_PTR pMechanism)
{
    OPENSSL_HEADER();
    
    OpenSSLDigestData* pDigData;
    const EVP_MD*      pDigest;
    CK_OBJECT_HANDLE   hKey   = CK_OBJECT_HANDLE_INVALID;
    bool               isHMAC = false;

    if(pSessionCtx            == NULL) return CKR_SESSION_CLOSED;
    if(pSessionCtx->DigestCtx != NULL) return CKR_SESSION_PARALLEL_NOT_SUPPORTED; // another digest is in progress
    
    pDigData = (OpenSSLDigestData*)TINYCLR_SSL_MALLOC(sizeof(*pDigData));

    if(pDigData == NULL) return CKR_DEVICE_MEMORY;

    TINYCLR_SSL_MEMSET(pDigData, 0, sizeof(*pDigData));
    
    EVP_MD_CTX_init(&pDigData->CurrentCtx);
    
    switch(pMechanism->mechanism)
    {
        case CKM_SHA_1:
            pDigest = EVP_sha1();
            break;
        case CKM_SHA224:
            pDigest = EVP_sha224();
            break;
        case CKM_SHA256:
            pDigest = EVP_sha256();
            break;
        case CKM_SHA384:
            pDigest = EVP_sha384();
            break;
        case CKM_SHA512:
            pDigest = EVP_sha512();
            break;

        case CKM_MD5:
            pDigest = EVP_md5();
            break;

        case CKM_RIPEMD160:
            pDigest = EVP_ripemd160();
            break;

        case CKM_MD5_HMAC:
            pDigest = EVP_md5();
            isHMAC = true;
            break;

        case CKM_SHA_1_HMAC:
            pDigest = EVP_sha1();
            isHMAC = true;
            break;

        case CKM_SHA256_HMAC:
            pDigest = EVP_sha256();
            isHMAC = true;
            break;

        case CKM_SHA384_HMAC:
            pDigest = EVP_sha384();
            isHMAC = true;
            break;

        case CKM_SHA512_HMAC:
            pDigest = EVP_sha512();
            isHMAC = true;
            break;

        case CKM_RIPEMD160_HMAC:
            pDigest = EVP_ripemd160();
            isHMAC = true;
            break;
            

        default:
            OPENSSL_SET_AND_LEAVE(CKR_MECHANISM_INVALID);
    }


    if(isHMAC)
    {
        if(pMechanism->pParameter != NULL && pMechanism->ulParameterLen == sizeof(CK_OBJECT_HANDLE))
        {
            hKey = SwapEndianIfBEc32(*(CK_OBJECT_HANDLE*)pMechanism->pParameter);
        }
        else 
        {
            OPENSSL_SET_AND_LEAVE(CKR_MECHANISM_PARAM_INVALID);
        }

        pDigData->HmacKey = PKCS11_Keys_OpenSSL::GetKeyFromHandle(pSessionCtx, hKey, TRUE);

        if(pDigData->HmacKey==NULL) OPENSSL_SET_AND_LEAVE(CKR_MECHANISM_PARAM_INVALID);

        pDigData->HmacCtx.md = pDigest;

        OPENSSL_CHECKRESULT(HMAC_Init(&pDigData->HmacCtx, pDigData->HmacKey->key, pDigData->HmacKey->size/8, pDigData->HmacCtx.md));
    }
    else
    {
        OPENSSL_CHECKRESULT(EVP_DigestInit_ex(&pDigData->CurrentCtx, pDigest, NULL));
    }
    
    pSessionCtx->DigestCtx = pDigData;
    
    OPENSSL_CLEANUP();
    if(retVal != CKR_OK && pDigData != NULL)
    {
        TINYCLR_SSL_FREE(pDigData);
    }
    OPENSSL_RETURN();
}
Ejemplo n.º 12
0
int EVP_PBE_scrypt(const char *pass, size_t passlen,
                   const unsigned char *salt, size_t saltlen,
                   uint64_t N, uint64_t r, uint64_t p, uint64_t maxmem,
                   unsigned char *key, size_t keylen)
{
    int rv = 0;
    unsigned char *B;
    uint32_t *X, *V, *T;
    uint64_t i, Blen, Vlen;
    size_t allocsize;

    /* Sanity check parameters */
    /* initial check, r,p must be non zero, N >= 2 and a power of 2 */
    if (r == 0 || p == 0 || N < 2 || (N & (N - 1)))
        return 0;
    /* Check p * r < SCRYPT_PR_MAX avoiding overflow */
    if (p > SCRYPT_PR_MAX / r) {
        EVPerr(EVP_F_EVP_PBE_SCRYPT, EVP_R_MEMORY_LIMIT_EXCEEDED);
        return 0;
    }

    /*
     * Need to check N: if 2^(128 * r / 8) overflows limit this is
     * automatically satisfied since N <= UINT64_MAX.
     */

    if (16 * r <= LOG2_UINT64_MAX) {
        if (N >= (((uint64_t)1) << (16 * r))) {
            EVPerr(EVP_F_EVP_PBE_SCRYPT, EVP_R_MEMORY_LIMIT_EXCEEDED);
            return 0;
        }
    }

    /* Memory checks: check total allocated buffer size fits in uint64_t */

    /*
     * B size in section 5 step 1.S
     * Note: we know p * 128 * r < UINT64_MAX because we already checked
     * p * r < SCRYPT_PR_MAX
     */
    Blen = p * 128 * r;

    /*
     * Check 32 * r * (N + 2) * sizeof(uint32_t) fits in
     * uint64_t and also size_t (their sizes are unrelated).
     * This is combined size V, X and T (section 4)
     */
    i = UINT64_MAX / (32 * sizeof(uint32_t));
    if (N + 2 > i / r) {
        EVPerr(EVP_F_EVP_PBE_SCRYPT, EVP_R_MEMORY_LIMIT_EXCEEDED);
        return 0;
    }
    Vlen = 32 * r * (N + 2) * sizeof(uint32_t);

    /* check total allocated size fits in uint64_t */
    if (Blen > UINT64_MAX - Vlen) {
        EVPerr(EVP_F_EVP_PBE_SCRYPT, EVP_R_MEMORY_LIMIT_EXCEEDED);
        return 0;
    }
    /* check total allocated size fits in size_t */
    if (Blen > SIZE_MAX - Vlen)
        return 0;

    allocsize = (size_t)(Blen + Vlen);

    if (maxmem == 0)
        maxmem = SCRYPT_MAX_MEM;

    if (allocsize > maxmem) {
        EVPerr(EVP_F_EVP_PBE_SCRYPT, EVP_R_MEMORY_LIMIT_EXCEEDED);
        return 0;
    }

    /* If no key return to indicate parameters are OK */
    if (key == NULL)
        return 1;

    B = OPENSSL_malloc(allocsize);
    if (B == NULL) {
        EVPerr(EVP_F_EVP_PBE_SCRYPT, ERR_R_MALLOC_FAILURE);
        return 0;
    }
    X = (uint32_t *)(B + Blen);
    T = X + 32 * r;
    V = T + 32 * r;
    if (PKCS5_PBKDF2_HMAC(pass, passlen, salt, saltlen, 1, EVP_sha256(),
                          Blen, B) == 0)
        goto err;

    for (i = 0; i < p; i++)
        scryptROMix(B + 128 * r * i, r, N, X, T, V);

    if (PKCS5_PBKDF2_HMAC(pass, passlen, B, Blen, 1, EVP_sha256(),
                          keylen, key) == 0)
        goto err;
    rv = 1;
 err:
    if (rv == 0)
        EVPerr(EVP_F_EVP_PBE_SCRYPT, EVP_R_PBKDF2_ERROR);

    OPENSSL_clear_free(B, allocsize);
    return rv;
}
Ejemplo n.º 13
0
Archivo: jwk.c Proyecto: tgorol/cjose
cjose_jwk_t *cjose_jwk_derive_ecdh_ephemeral_key(
        cjose_jwk_t *jwk_self,
        cjose_jwk_t *jwk_peer,
        cjose_err *err) 
{
    EVP_PKEY_CTX *ctx = NULL;
    EVP_PKEY *pkey_self = NULL;
    EVP_PKEY *pkey_peer = NULL;
    uint8_t *secret = NULL;
    size_t secret_len = 0;
    uint8_t *ephemeral_key = NULL;
    size_t ephemeral_key_len = 0;
    cjose_jwk_t *jwk_ephemeral_key = NULL;

    // get EVP_KEY from jwk_self
    if (!_cjose_jwk_evp_key_from_ec_key(jwk_self, &pkey_self, err))
    {
        goto _cjose_jwk_derive_shared_secret_fail;
    }

    // get EVP_KEY from jwk_peer
    if (!_cjose_jwk_evp_key_from_ec_key(jwk_peer, &pkey_peer, err))
    {
        goto _cjose_jwk_derive_shared_secret_fail;
    }

    // create derivation context based on local key pair
    ctx = EVP_PKEY_CTX_new(pkey_self, NULL);
    if (NULL == ctx)
    {
        CJOSE_ERROR(err, CJOSE_ERR_CRYPTO);
        goto _cjose_jwk_derive_shared_secret_fail;
    }

    // initialize derivation context
    if (1 != EVP_PKEY_derive_init(ctx))
    {
        CJOSE_ERROR(err, CJOSE_ERR_CRYPTO);
        goto _cjose_jwk_derive_shared_secret_fail;
    }

    // provide the peer public key
    if (1 != EVP_PKEY_derive_set_peer(ctx, pkey_peer))
    {
        CJOSE_ERROR(err, CJOSE_ERR_CRYPTO);
        goto _cjose_jwk_derive_shared_secret_fail;
    }

    // determine buffer length for shared secret
    if(1 != EVP_PKEY_derive(ctx, NULL, &secret_len))
    {
        CJOSE_ERROR(err, CJOSE_ERR_CRYPTO);
        goto _cjose_jwk_derive_shared_secret_fail;
    }

    // allocate buffer for shared secret
    secret = (uint8_t *)cjose_get_alloc()(secret_len);
    if (NULL == secret)
    {
        CJOSE_ERROR(err, CJOSE_ERR_NO_MEMORY);
        goto _cjose_jwk_derive_shared_secret_fail;        
    }
    memset(secret, 0, secret_len);

    // derive the shared secret
    if (1 != (EVP_PKEY_derive(ctx, secret, &secret_len)))
    {
        CJOSE_ERROR(err, CJOSE_ERR_NO_MEMORY);
        goto _cjose_jwk_derive_shared_secret_fail;                
    }

    // HKDF of the DH shared secret (SHA256, no salt, no info, 256 bit expand)
    ephemeral_key_len = 32;
    ephemeral_key = (uint8_t *)cjose_get_alloc()(ephemeral_key_len);
    if (!cjose_jwk_hkdf(EVP_sha256(), (uint8_t *)"", 0, (uint8_t *)"", 0, 
            secret, secret_len, ephemeral_key, ephemeral_key_len, err))
    {
        goto _cjose_jwk_derive_shared_secret_fail;        
    }

    // create a JWK of the shared secret
    jwk_ephemeral_key = cjose_jwk_create_oct_spec(
            ephemeral_key, ephemeral_key_len, err);
    if (NULL == jwk_ephemeral_key)
    {
        goto _cjose_jwk_derive_shared_secret_fail;        
    }

    // happy path
    EVP_PKEY_CTX_free(ctx);
    EVP_PKEY_free(pkey_self);
    EVP_PKEY_free(pkey_peer);
    cjose_get_dealloc()(secret);
    cjose_get_dealloc()(ephemeral_key);

    return jwk_ephemeral_key;

    // fail path
    _cjose_jwk_derive_shared_secret_fail:
    
    if (NULL != ctx)
    {
        EVP_PKEY_CTX_free(ctx);
    }
    if (NULL != pkey_self)
    {
        EVP_PKEY_free(pkey_self);
    }
    if (NULL != pkey_peer)
    {
        EVP_PKEY_free(pkey_peer);
    }
    if (NULL != jwk_ephemeral_key)
    {
        cjose_jwk_release(jwk_ephemeral_key);
    }
    cjose_get_dealloc()(secret);
    cjose_get_dealloc()(ephemeral_key);
    return NULL;
}
Ejemplo n.º 14
0
bool find_server(EVP_PKEY *pk, sockaddr6 *addr, uint32_t usecs, uint32_t retries) {
    bool ok = false;

    interface ifs[16];
    ssize_t count = active_interfaces(ifs, 16);
    if (count <= 0) return false;

    addr->sin6_family   = AF_INET6;
    addr->sin6_port     = htons(atoi(MCAST_PORT));
    addr->sin6_scope_id = ifs[0].index;
    inet_pton(AF_INET6, MCAST_HOST, &addr->sin6_addr);

    int fd = socket(AF_INET6, SOCK_DGRAM, IPPROTO_UDP);
    if (fd == -1) return false;

    struct ipv6_mreq req = { .ipv6mr_interface = ifs[0].index };
    memcpy(&req.ipv6mr_multiaddr, &addr->sin6_addr, sizeof(struct in6_addr));
    if (setsockopt(fd, IPPROTO_IPV6, IPV6_JOIN_GROUP, &req, sizeof(req))) {
        return false;
    }

    struct timeval timeout = { .tv_usec = usecs / retries };
    setsockopt(fd, SOL_SOCKET, SO_RCVTIMEO, &timeout, sizeof(timeout));

    sockaddr6 from6;
    socklen_t from_len = sizeof(from6);
    sockaddr *from = (sockaddr *) &from6;

    uint8_t ping[PING_LEN];
    struct pong pong;
    ssize_t len;

    RAND_bytes(ping, PING_LEN);

    for (uint32_t i = 0; !ok && i < retries; i++) {
        EVP_MD_CTX ctx;

        sendto(fd, ping, PING_LEN, 0, (sockaddr *) addr, sizeof(*addr));

        if ((len = recvfrom(fd, &pong, sizeof(pong), 0, from, &from_len)) > 0) {
            EVP_MD_CTX_init(&ctx);
            EVP_DigestVerifyInit(&ctx, NULL, EVP_sha256(), NULL, pk);
            EVP_DigestVerifyUpdate(&ctx, &ping, PING_LEN);
            EVP_DigestVerifyUpdate(&ctx, &pong, PONG_LEN);

            if (EVP_DigestVerifyFinal(&ctx, pong.sig, len) == 1) {
                memcpy(addr->sin6_addr.s6_addr, &pong.addr, 16);
                addr->sin6_port = pong.port;
                ok = true;
            }

            EVP_MD_CTX_cleanup(&ctx);
        }
    }
    close(fd);

    return ok;
}

int mcast_sock(interface *ifa, sockaddr6 *addr, char *host) {
    struct ipv6_mreq req = { .ipv6mr_interface = ifa->index };
    inet_pton(AF_INET6, host, &req.ipv6mr_multiaddr);

    int fd = socket(AF_INET6, SOCK_DGRAM, IPPROTO_UDP);
    if (fd == -1 || bind(fd, (sockaddr *) addr, sizeof(*addr))) goto error;
    if (setsockopt(fd, IPPROTO_IPV6, IPV6_JOIN_GROUP, &req, sizeof(req))) goto error;

    return fd;

  error:

    if (fd >= 0) close(fd);
    return -1;
}

char *name(sockaddr6 *addr, socklen_t len) {
    static char host[NI_MAXHOST];
    int flags = NI_NUMERICHOST;
    getnameinfo((struct sockaddr *) addr, len, host, NI_MAXHOST, NULL, 0, flags);
    return host;
}
Ejemplo n.º 15
0
bool PaymentRequestPlus::getMerchant(X509_STORE* certStore, QString& merchant) const
{
    merchant.clear();

    if (!IsInitialized())
        return false;

    // One day we'll support more PKI types, but just
    // x509 for now:
    const EVP_MD* digestAlgorithm = nullptr;
    if (paymentRequest.pki_type() == "x509+sha256") {
        digestAlgorithm = EVP_sha256();
    }
    else if (paymentRequest.pki_type() == "x509+sha1") {
        digestAlgorithm = EVP_sha1();
    }
    else if (paymentRequest.pki_type() == "none") {
        qWarning() << "PaymentRequestPlus::getMerchant: Payment request: pki_type == none";
        return false;
    }
    else {
        qWarning() << "PaymentRequestPlus::getMerchant: Payment request: unknown pki_type " << QString::fromStdString(paymentRequest.pki_type());
        return false;
    }

    payments::X509Certificates certChain;
    if (!certChain.ParseFromString(paymentRequest.pki_data())) {
        qWarning() << "PaymentRequestPlus::getMerchant: Payment request: error parsing pki_data";
        return false;
    }

    std::vector<X509*> certs;
    const QDateTime currentTime = QDateTime::currentDateTime();
    for (int i = 0; i < certChain.certificate_size(); i++) {
        QByteArray certData(certChain.certificate(i).data(), certChain.certificate(i).size());
        QSslCertificate qCert(certData, QSsl::Der);
        if (currentTime < qCert.effectiveDate() || currentTime > qCert.expiryDate()) {
            qWarning() << "PaymentRequestPlus::getMerchant: Payment request: certificate expired or not yet active: " << qCert;
            return false;
        }
#if QT_VERSION >= 0x050000
        if (qCert.isBlacklisted()) {
            qWarning() << "PaymentRequestPlus::getMerchant: Payment request: certificate blacklisted: " << qCert;
            return false;
        }
#endif
        const unsigned char *data = (const unsigned char *)certChain.certificate(i).data();
        X509 *cert = d2i_X509(nullptr, &data, certChain.certificate(i).size());
        if (cert)
            certs.push_back(cert);
    }
    if (certs.empty()) {
        qWarning() << "PaymentRequestPlus::getMerchant: Payment request: empty certificate chain";
        return false;
    }

    // The first cert is the signing cert, the rest are untrusted certs that chain
    // to a valid root authority. OpenSSL needs them separately.
    STACK_OF(X509) *chain = sk_X509_new_null();
    for (int i = certs.size() - 1; i > 0; i--) {
        sk_X509_push(chain, certs[i]);
    }
    X509 *signing_cert = certs[0];

    // Now create a "store context", which is a single use object for checking,
    // load the signing cert into it and verify.
    X509_STORE_CTX *store_ctx = X509_STORE_CTX_new();
    if (!store_ctx) {
        qWarning() << "PaymentRequestPlus::getMerchant: Payment request: error creating X509_STORE_CTX";
        return false;
    }

    char *website = nullptr;
    bool fResult = true;
    try
    {
        if (!X509_STORE_CTX_init(store_ctx, certStore, signing_cert, chain))
        {
            int error = X509_STORE_CTX_get_error(store_ctx);
            throw SSLVerifyError(X509_verify_cert_error_string(error));
        }

        // Now do the verification!
        int result = X509_verify_cert(store_ctx);
        if (result != 1) {
            int error = X509_STORE_CTX_get_error(store_ctx);
            // For testing payment requests, we allow self signed root certs!
            // This option is just shown in the UI options, if -help-debug is enabled.
            if (!(error == X509_V_ERR_DEPTH_ZERO_SELF_SIGNED_CERT && gArgs.GetBoolArg("-allowselfsignedrootcertificates", DEFAULT_SELFSIGNED_ROOTCERTS))) {
                throw SSLVerifyError(X509_verify_cert_error_string(error));
            } else {
               qDebug() << "PaymentRequestPlus::getMerchant: Allowing self signed root certificate, because -allowselfsignedrootcertificates is true.";
            }
        }
        X509_NAME *certname = X509_get_subject_name(signing_cert);

        // Valid cert; check signature:
        payments::PaymentRequest rcopy(paymentRequest); // Copy
        rcopy.set_signature(std::string(""));
        std::string data_to_verify;                     // Everything but the signature
        rcopy.SerializeToString(&data_to_verify);

#if HAVE_DECL_EVP_MD_CTX_NEW
        EVP_MD_CTX *ctx = EVP_MD_CTX_new();
        if (!ctx) throw SSLVerifyError("Error allocating OpenSSL context.");
#else
        EVP_MD_CTX _ctx;
        EVP_MD_CTX *ctx;
        ctx = &_ctx;
#endif
        EVP_PKEY *pubkey = X509_get_pubkey(signing_cert);
        EVP_MD_CTX_init(ctx);
        if (!EVP_VerifyInit_ex(ctx, digestAlgorithm, nullptr) ||
            !EVP_VerifyUpdate(ctx, data_to_verify.data(), data_to_verify.size()) ||
            !EVP_VerifyFinal(ctx, (const unsigned char*)paymentRequest.signature().data(), (unsigned int)paymentRequest.signature().size(), pubkey)) {
            throw SSLVerifyError("Bad signature, invalid payment request.");
        }
#if HAVE_DECL_EVP_MD_CTX_NEW
        EVP_MD_CTX_free(ctx);
#endif

        // OpenSSL API for getting human printable strings from certs is baroque.
        int textlen = X509_NAME_get_text_by_NID(certname, NID_commonName, nullptr, 0);
        website = new char[textlen + 1];
        if (X509_NAME_get_text_by_NID(certname, NID_commonName, website, textlen + 1) == textlen && textlen > 0) {
            merchant = website;
        }
        else {
            throw SSLVerifyError("Bad certificate, missing common name.");
        }
        // TODO: detect EV certificates and set merchant = business name instead of unfriendly NID_commonName ?
    }
    catch (const SSLVerifyError& err) {
        fResult = false;
        qWarning() << "PaymentRequestPlus::getMerchant: SSL error: " << err.what();
    }

    if (website)
        delete[] website;
    X509_STORE_CTX_free(store_ctx);
    for (unsigned int i = 0; i < certs.size(); i++)
        X509_free(certs[i]);

    return fResult;
}
void CC_SHA256(const void *data, uint32_t len, unsigned char *md)
{
	CC_EVP(EVP_sha256(), 32, data, len, md);
}
Ejemplo n.º 17
0
static int pbkdf2_encrypt(
	const struct berval *scheme,
	const struct berval *passwd,
	struct berval *msg,
	const char **text)
{
	unsigned char salt_value[PBKDF2_SALT_SIZE];
	struct berval salt;
	unsigned char dk_value[PBKDF2_MAX_DK_SIZE];
	struct berval dk;
	int iteration = PBKDF2_ITERATION;
	int rc;
#ifdef HAVE_OPENSSL
	const EVP_MD *md;
#elif HAVE_GNUTLS
	struct hmac_sha1_ctx sha1_ctx;
	struct hmac_sha256_ctx sha256_ctx;
	struct hmac_sha512_ctx sha512_ctx;
	void * current_ctx = NULL;
	pbkdf2_hmac_update current_hmac_update = NULL;
	pbkdf2_hmac_digest current_hmac_digest = NULL;
#endif

	salt.bv_val = (char *)salt_value;
	salt.bv_len = sizeof(salt_value);
	dk.bv_val = (char *)dk_value;

#ifdef HAVE_OPENSSL
	if(!ber_bvcmp(scheme, &pbkdf2_scheme)){
		dk.bv_len = PBKDF2_SHA1_DK_SIZE;
		md = EVP_sha1();
	}else if(!ber_bvcmp(scheme, &pbkdf2_sha1_scheme)){
		dk.bv_len = PBKDF2_SHA1_DK_SIZE;
		md = EVP_sha1();
	}else if(!ber_bvcmp(scheme, &pbkdf2_sha256_scheme)){
		dk.bv_len = PBKDF2_SHA256_DK_SIZE;
		md = EVP_sha256();
	}else if(!ber_bvcmp(scheme, &pbkdf2_sha512_scheme)){
		dk.bv_len = PBKDF2_SHA512_DK_SIZE;
		md = EVP_sha512();
	}else{
		return LUTIL_PASSWD_ERR;
	}
#elif HAVE_GNUTLS
	if(!ber_bvcmp(scheme, &pbkdf2_scheme)){
		dk.bv_len = PBKDF2_SHA1_DK_SIZE;
		current_ctx = &sha1_ctx;
		current_hmac_update = (pbkdf2_hmac_update) &hmac_sha1_update;
		current_hmac_digest = (pbkdf2_hmac_digest) &hmac_sha1_digest;
		hmac_sha1_set_key(current_ctx, passwd->bv_len, (const uint8_t *) passwd->bv_val);
	}else if(!ber_bvcmp(scheme, &pbkdf2_sha1_scheme)){
		dk.bv_len = PBKDF2_SHA1_DK_SIZE;
		current_ctx = &sha1_ctx;
		current_hmac_update = (pbkdf2_hmac_update) &hmac_sha1_update;
		current_hmac_digest = (pbkdf2_hmac_digest) &hmac_sha1_digest;
		hmac_sha1_set_key(current_ctx, passwd->bv_len, (const uint8_t *) passwd->bv_val);
	}else if(!ber_bvcmp(scheme, &pbkdf2_sha256_scheme)){
		dk.bv_len = PBKDF2_SHA256_DK_SIZE;
		current_ctx = &sha256_ctx;
		current_hmac_update = (pbkdf2_hmac_update) &hmac_sha256_update;
		current_hmac_digest = (pbkdf2_hmac_digest) &hmac_sha256_digest;
		hmac_sha256_set_key(current_ctx, passwd->bv_len, (const uint8_t *) passwd->bv_val);
	}else if(!ber_bvcmp(scheme, &pbkdf2_sha512_scheme)){
		dk.bv_len = PBKDF2_SHA512_DK_SIZE;
		current_ctx = &sha512_ctx;
		current_hmac_update = (pbkdf2_hmac_update) &hmac_sha512_update;
		current_hmac_digest = (pbkdf2_hmac_digest) &hmac_sha512_digest;
		hmac_sha512_set_key(current_ctx, passwd->bv_len, (const uint8_t *) passwd->bv_val);
	}else{
		return LUTIL_PASSWD_ERR;
	}
#endif

	if(lutil_entropy((unsigned char *)salt.bv_val, salt.bv_len) < 0){
		return LUTIL_PASSWD_ERR;
	}

#ifdef HAVE_OPENSSL
	if(!PKCS5_PBKDF2_HMAC(passwd->bv_val, passwd->bv_len,
						  (unsigned char *)salt.bv_val, salt.bv_len,
						  iteration, md, dk.bv_len, dk_value)){
		return LUTIL_PASSWD_ERR;
	}
#elif HAVE_GNUTLS
	PBKDF2(current_ctx, current_hmac_update, current_hmac_digest,
						  dk.bv_len, iteration,
						  salt.bv_len, (const uint8_t *) salt.bv_val,
						  dk.bv_len, dk_value);
#endif

#ifdef SLAPD_PBKDF2_DEBUG
	printf("Encrypt for %s\n", scheme->bv_val);
	printf("  Password:\t%s\n", passwd->bv_val);

	printf("  Salt:\t\t");
	int i;
	for(i=0; i<salt.bv_len; i++){
		printf("%02x", salt_value[i]);
	}
	printf("\n");
	printf("  Iteration:\t%d\n", iteration);

	printf("  DK:\t\t");
	for(i=0; i<dk.bv_len; i++){
		printf("%02x", dk_value[i]);
	}
	printf("\n");
#endif

	rc = pbkdf2_format(scheme, iteration, &salt, &dk, msg);

#ifdef SLAPD_PBKDF2_DEBUG
	printf("  Output:\t%s\n", msg->bv_val);
#endif

	return rc;
}
Ejemplo n.º 18
0
enum nssync_error
nssync_crypto_decrypt_record(const char *record,
			     struct nssync_crypto_keybundle *keybundle,
			     uint8_t **plaintext_out,
			     size_t *plaintext_length_out)
{
	/* json objects */
	json_t *root;
	json_error_t error;
	json_t *hmac_hex16_json;
	json_t *ciphertext_b64_json;
	json_t *iv_b64_json;

	/* text from json */
	const char *hmac_hex16;
	const char *ciphertext_b64;
	const char *iv_b64;

	/* HMAC from record */
	uint8_t *record_hmac;
	size_t record_hmac_length = HMAC_KEY_LENGTH;

	/* HMAC computed from key */
	unsigned int local_hmac_length = HMAC_KEY_LENGTH;
	uint8_t local_hmac[HMAC_KEY_LENGTH];

	/* decoded ciphertext */
	uint8_t *ciphertext;
	size_t ciphertext_length;
	uint8_t *iv;
	size_t iv_length;

	/* AES state */
	AES_KEY aeskey;

	/* decypted data */
	uint8_t *plaintext;

	/* json load */
	root = json_loads(record, 0, &error);
	if (!root) {
		debugf("error: on line %d of reply: %s\n",
			error.line, error.text);
		return NSSYNC_ERROR_PROTOCOL;
	}

	if(!json_is_object(root)) {
		debugf("error: root is not an object\n");
		json_decref(root);
		return NSSYNC_ERROR_PROTOCOL;
	}

	/* extract ciphertext from record (undecoded) */

	hmac_hex16_json = json_object_get(root, "hmac");
	ciphertext_b64_json = json_object_get(root, "ciphertext");
	iv_b64_json = json_object_get(root, "IV");
	if ((!json_is_string(hmac_hex16_json)) ||
	    (!json_is_string(ciphertext_b64_json)) ||
	    (!json_is_string(iv_b64_json))) {
		debugf("missing or incorrectly formatted fields in record\n");
		json_decref(root);
		return NSSYNC_ERROR_PROTOCOL;
	}
	hmac_hex16 = json_string_value(hmac_hex16_json);
	ciphertext_b64 = json_string_value(ciphertext_b64_json);
	iv_b64 = json_string_value(iv_b64_json);

	/* hex16 decode hmac from record */
	record_hmac = hex16_decode((uint8_t *)hmac_hex16,
				   strlen(hmac_hex16),
				   &record_hmac_length);
	if (record_hmac_length != HMAC_KEY_LENGTH) {
		debugf("record hmac length %zu incorrect (should be %d)\n",
			record_hmac_length, HMAC_KEY_LENGTH);
		json_decref(root);
		return NSSYNC_ERROR_PROTOCOL;
	}

	/* calculate local hmac value */
	HMAC(EVP_sha256(),
	     keybundle->hmac, HMAC_KEY_LENGTH,
	     (uint8_t *)ciphertext_b64, strlen(ciphertext_b64),
	     local_hmac, &local_hmac_length);

	/* verify hmac */
	if (memcmp(record_hmac, local_hmac, SHA256_DIGEST_LENGTH) != 0) {
		debugf("record hmac does not match computed. bad key?\n");
		free(record_hmac);
		json_decref(root);
		return NSSYNC_ERROR_HMAC;
	}
	free(record_hmac);

	/* base64 decode iv from record */
	iv = base64_decode((uint8_t *)iv_b64,
			   strlen(iv_b64),
			   &iv_length);
	if ((iv == NULL) || (iv_length != IV_LENGTH)) {
		debugf("IV data was size %zu (expected %d)\n",
			iv_length, IV_LENGTH);
		json_decref(root);
		return NSSYNC_ERROR_PROTOCOL;
	}

	/* base64 decode ciphertext */
	ciphertext = base64_decode((uint8_t *)ciphertext_b64,
				   strlen(ciphertext_b64),
				   &ciphertext_length);
	if (ciphertext == NULL) {
		json_decref(root);
		free(iv);
		return NSSYNC_ERROR_NOMEM;
	}

	/* json unref */
	json_decref(root);

	/* decrypt data */
	plaintext = malloc(ciphertext_length + 1);
	if (plaintext == NULL) {
		free(ciphertext);
		free(iv);
		return NSSYNC_ERROR_NOMEM;
	}
	plaintext[ciphertext_length] = 0;

	AES_set_decrypt_key(keybundle->encryption, 256, &aeskey);
	AES_cbc_encrypt(ciphertext, plaintext, ciphertext_length, &aeskey, iv, AES_DECRYPT);

	free(ciphertext);
	free(iv);

	*plaintext_out = plaintext;
	if (plaintext_length_out != NULL) {
		*plaintext_length_out = ciphertext_length;
	}

	return NSSYNC_ERROR_OK;
}
Ejemplo n.º 19
0
int hmac_test(const EVP_MD *md, FILE *out, FILE *in)
	{
	char *linebuf, *olinebuf, *p, *q;
	char *keyword, *value;
	unsigned char *Key = NULL, *Msg = NULL;
	int Count, Klen, Tlen;
	long Keylen, Msglen;
	int ret = 0;
	int lnum = 0;

	olinebuf = OPENSSL_malloc(HMAC_TEST_MAXLINELEN);
	linebuf = OPENSSL_malloc(HMAC_TEST_MAXLINELEN);

	if (!linebuf || !olinebuf)
		goto error;

	Count = -1;
	Klen = -1;
	Tlen = -1;

	while (fgets(olinebuf, HMAC_TEST_MAXLINELEN, in))
		{
		lnum++;
		strcpy(linebuf, olinebuf);
		keyword = linebuf;
		/* Skip leading space */
		while (isspace((unsigned char)*keyword))
			keyword++;

		/* Look for = sign */
		p = strchr(linebuf, '=');

		/* If no = or starts with [ (for [L=20] line) just copy */
		if (!p)
			{
			if (fputs(olinebuf, out) < 0)
				goto error;
			continue;
			}

		q = p - 1;

		/* Remove trailing space */
		while (isspace((unsigned char)*q))
			*q-- = 0;

		*p = 0;
		value = p + 1;

		/* Remove leading space from value */
		while (isspace((unsigned char)*value))
			value++;

		/* Remove trailing space from value */
		p = value + strlen(value) - 1;

		while (*p == '\n' || isspace((unsigned char)*p))
			*p-- = 0;

		if (!strcmp(keyword,"[L") && *p==']')
			{
			switch (atoi(value))
				{
				case 20: md=EVP_sha1();   break;
				case 28: md=EVP_sha224(); break;
				case 32: md=EVP_sha256(); break;
				case 48: md=EVP_sha384(); break;
				case 64: md=EVP_sha512(); break;
				default: goto parse_error;
				}
			}
		else if (!strcmp(keyword, "Count"))
			{
			if (Count != -1)
				goto parse_error;
			Count = atoi(value);
			if (Count < 0)
				goto parse_error;
			}
		else if (!strcmp(keyword, "Klen"))
			{
			if (Klen != -1)
				goto parse_error;
			Klen = atoi(value);
			if (Klen < 0)
				goto parse_error;
			}
		else if (!strcmp(keyword, "Tlen"))
			{
			if (Tlen != -1)
				goto parse_error;
			Tlen = atoi(value);
			if (Tlen < 0)
				goto parse_error;
			}
		else if (!strcmp(keyword, "Msg"))
			{
			if (Msg)
				goto parse_error;
			Msg = hex2bin_m(value, &Msglen);
			if (!Msg)
				goto parse_error;
			}
		else if (!strcmp(keyword, "Key"))
			{
			if (Key)
				goto parse_error;
			Key = hex2bin_m(value, &Keylen);
			if (!Key)
				goto parse_error;
			}
		else if (!strcmp(keyword, "Mac"))
			continue;
		else
			goto parse_error;

		fputs(olinebuf, out);

		if (Key && Msg && (Tlen > 0) && (Klen > 0))
			{
			if (!print_hmac(md, out, Key, Klen, Msg, Msglen, Tlen))
				goto error;
			OPENSSL_free(Key);
			Key = NULL;
			OPENSSL_free(Msg);
			Msg = NULL;
			Klen = -1;
			Tlen = -1;
			Count = -1;
			}

		}


	ret = 1;


	error:

	if (olinebuf)
		OPENSSL_free(olinebuf);
	if (linebuf)
		OPENSSL_free(linebuf);
	if (Key)
		OPENSSL_free(Key);
	if (Msg)
		OPENSSL_free(Msg);

	return ret;

	parse_error:

	fprintf(stderr, "FATAL parse error processing line %d\n", lnum);

	goto error;

	}
Ejemplo n.º 20
0
bool OSSLRSA::signFinal(ByteString& signature)
{
	// Save necessary state before calling super class signFinal
	OSSLRSAPrivateKey* pk = (OSSLRSAPrivateKey*) currentPrivateKey;
	AsymMech::Type mechanism = currentMechanism;

	if (!AsymmetricAlgorithm::signFinal(signature))
	{
		return false;
	}

	ByteString firstHash, secondHash;

	bool bFirstResult = pCurrentHash->hashFinal(firstHash);
	bool bSecondResult = (pSecondHash != NULL) ? pSecondHash->hashFinal(secondHash) : true;

	delete pCurrentHash;
	pCurrentHash = NULL;

	if (pSecondHash != NULL)
	{
		delete pSecondHash;

		pSecondHash = NULL;
	}

	if (!bFirstResult || !bSecondResult)
	{
		return false;
	}

	ByteString digest = firstHash + secondHash;

	// Resize the data block for the signature to the modulus size of the key
	signature.resize(pk->getN().size());

	// Determine the signature NID type
	int type = 0;
	bool isPSS = false;
	const EVP_MD* hash = NULL;

	switch (mechanism)
	{
		case AsymMech::RSA_MD5_PKCS:
			type = NID_md5;
			break;
		case AsymMech::RSA_SHA1_PKCS:
			type = NID_sha1;
			break;
		case AsymMech::RSA_SHA224_PKCS:
			type = NID_sha224;
			break;
		case AsymMech::RSA_SHA256_PKCS:
			type = NID_sha256;
			break;
		case AsymMech::RSA_SHA384_PKCS:
			type = NID_sha384;
			break;
		case AsymMech::RSA_SHA512_PKCS:
			type = NID_sha512;
			break;
		case AsymMech::RSA_SHA1_PKCS_PSS:
			isPSS = true;
			hash = EVP_sha1();
			break;
		case AsymMech::RSA_SHA224_PKCS_PSS:
			isPSS = true;
			hash = EVP_sha224();
			break;
		case AsymMech::RSA_SHA256_PKCS_PSS:
			isPSS = true;
			hash = EVP_sha256();
			break;
		case AsymMech::RSA_SHA384_PKCS_PSS:
			isPSS = true;
			hash = EVP_sha384();
			break;
		case AsymMech::RSA_SHA512_PKCS_PSS:
			isPSS = true;
			hash = EVP_sha512();
			break;
		case AsymMech::RSA_SSL:
			type = NID_md5_sha1;
			break;
		default:
			break;
	}

	// Perform the signature operation
	unsigned int sigLen = signature.size();

	RSA* rsa = pk->getOSSLKey();

	if (!RSA_blinding_on(rsa, NULL))
	{
		ERROR_MSG("Failed to turn blinding on for OpenSSL RSA key");

		return false;
	}

	bool rv;

	if (isPSS)
	{
		ByteString em;
		em.resize(pk->getN().size());

		rv = (RSA_padding_add_PKCS1_PSS(pk->getOSSLKey(), &em[0], &digest[0],
						hash, sLen) == 1);
		if (!rv)
		{
			ERROR_MSG("RSA PSS padding failed (0x%08X)", ERR_get_error());
		}
		else
		{
			int result = RSA_private_encrypt(em.size(), &em[0], &signature[0],
							 pk->getOSSLKey(), RSA_NO_PADDING);
			if (result >= 0)
			{
				sigLen = result;
				rv = true;
			}
			else
			{
				rv = false;
				ERROR_MSG("RSA private encrypt failed (0x%08X)", ERR_get_error());
			}
		}
	}
	else
	{
		rv = (RSA_sign(type, &digest[0], digest.size(), &signature[0],
			       &sigLen, pk->getOSSLKey()) == 1);
	}

	RSA_blinding_off(rsa);

	signature.resize(sigLen);

	return rv;
}
Ejemplo n.º 21
0
const EVP_MD* CryptoNative_EvpSha256()
{
    return EVP_sha256();
}
Ejemplo n.º 22
0
/**
 * @brief Build client-final-message
 * @returns -1 on error.
 */
static int
rd_kafka_sasl_scram_build_client_final_message (
        rd_kafka_transport_t *rktrans,
        const rd_chariov_t *salt,
        const char *server_nonce,
        const rd_chariov_t *server_first_msg,
        int itcnt, rd_chariov_t *out) {
        struct rd_kafka_sasl_scram_state *state = rktrans->rktrans_sasl.state;
        const rd_kafka_conf_t *conf = &rktrans->rktrans_rkb->rkb_rk->rk_conf;
        rd_chariov_t SaslPassword =
                { .ptr = conf->sasl.password,
                  .size = strlen(conf->sasl.password) };
        rd_chariov_t SaltedPassword =
                { .ptr = rd_alloca(EVP_MAX_MD_SIZE) };
        rd_chariov_t ClientKey =
                { .ptr = rd_alloca(EVP_MAX_MD_SIZE) };
        rd_chariov_t ServerKey =
                { .ptr = rd_alloca(EVP_MAX_MD_SIZE) };
        rd_chariov_t StoredKey =
                { .ptr = rd_alloca(EVP_MAX_MD_SIZE) };
        rd_chariov_t AuthMessage = RD_ZERO_INIT;
        rd_chariov_t ClientSignature =
                { .ptr = rd_alloca(EVP_MAX_MD_SIZE) };
        rd_chariov_t ServerSignature =
                { .ptr = rd_alloca(EVP_MAX_MD_SIZE) };
        const rd_chariov_t ClientKeyVerbatim =
                { .ptr = "Client Key", .size = 10 };
        const rd_chariov_t ServerKeyVerbatim =
                { .ptr = "Server Key", .size = 10 };
        rd_chariov_t ClientProof =
                { .ptr = rd_alloca(EVP_MAX_MD_SIZE) };
        rd_chariov_t client_final_msg_wo_proof;
        char *ClientProofB64;
        int i;

        /* Constructing the ClientProof attribute (p):
         *
         * p = Base64-encoded ClientProof
         * SaltedPassword  := Hi(Normalize(password), salt, i)
         * ClientKey       := HMAC(SaltedPassword, "Client Key")
         * StoredKey       := H(ClientKey)
         * AuthMessage     := client-first-message-bare + "," +
         *                    server-first-message + "," +
         *                    client-final-message-without-proof
         * ClientSignature := HMAC(StoredKey, AuthMessage)
         * ClientProof     := ClientKey XOR ClientSignature
         * ServerKey       := HMAC(SaltedPassword, "Server Key")
         * ServerSignature := HMAC(ServerKey, AuthMessage)
         */

        /* SaltedPassword  := Hi(Normalize(password), salt, i) */
        if (rd_kafka_sasl_scram_Hi(
                    rktrans, &SaslPassword, salt,
                    itcnt, &SaltedPassword) == -1)
                return -1;

        /* ClientKey       := HMAC(SaltedPassword, "Client Key") */
        if (rd_kafka_sasl_scram_HMAC(
                    rktrans, &SaltedPassword, &ClientKeyVerbatim,
                    &ClientKey) == -1)
                return -1;

        /* StoredKey       := H(ClientKey) */
        if (rd_kafka_sasl_scram_H(rktrans, &ClientKey, &StoredKey) == -1)
                return -1;

        /* client-final-message-without-proof */
        rd_kafka_sasl_scram_build_client_final_message_wo_proof(
                state, server_nonce, &client_final_msg_wo_proof);

        /* AuthMessage     := client-first-message-bare + "," +
         *                    server-first-message + "," +
         *                    client-final-message-without-proof */
        AuthMessage.size =
                state->first_msg_bare.size + 1 +
                server_first_msg->size + 1 +
                client_final_msg_wo_proof.size;
        AuthMessage.ptr = rd_alloca(AuthMessage.size+1);
        rd_snprintf(AuthMessage.ptr, AuthMessage.size+1,
                    "%.*s,%.*s,%.*s",
                    (int)state->first_msg_bare.size, state->first_msg_bare.ptr,
                    (int)server_first_msg->size, server_first_msg->ptr,
                    (int)client_final_msg_wo_proof.size,
                    client_final_msg_wo_proof.ptr);

        /*
         * Calculate ServerSignature for later verification when
         * server-final-message is received.
         */

        /* ServerKey       := HMAC(SaltedPassword, "Server Key") */
        if (rd_kafka_sasl_scram_HMAC(
                    rktrans, &SaltedPassword, &ServerKeyVerbatim,
                    &ServerKey) == -1) {
                rd_free(client_final_msg_wo_proof.ptr);
                return -1;
        }

        /* ServerSignature := HMAC(ServerKey, AuthMessage) */
        if (rd_kafka_sasl_scram_HMAC(rktrans, &ServerKey,
                                     &AuthMessage, &ServerSignature) == -1) {
                rd_free(client_final_msg_wo_proof.ptr);
                return -1;
        }

        /* Store the Base64 encoded ServerSignature for quick comparison */
        state->ServerSignatureB64 = rd_base64_encode(&ServerSignature);


        /*
         * Continue with client-final-message
         */

        /* ClientSignature := HMAC(StoredKey, AuthMessage) */
        if (rd_kafka_sasl_scram_HMAC(rktrans, &StoredKey,
                                     &AuthMessage, &ClientSignature) == -1) {
                rd_free(client_final_msg_wo_proof.ptr);
                return -1;
        }

        /* ClientProof     := ClientKey XOR ClientSignature */
        assert(ClientKey.size == ClientSignature.size);
        for (i = 0 ; i < (int)ClientKey.size ; i++)
                ClientProof.ptr[i] = ClientKey.ptr[i] ^ ClientSignature.ptr[i];
        ClientProof.size = ClientKey.size;


        /* Base64 encoded ClientProof */
        ClientProofB64 = rd_base64_encode(&ClientProof);

        /* Construct client-final-message */
        out->size = client_final_msg_wo_proof.size +
                strlen(",p=") + strlen(ClientProofB64);
        out->ptr = rd_malloc(out->size + 1);

        rd_snprintf(out->ptr, out->size+1,
                    "%.*s,p=%s",
                    (int)client_final_msg_wo_proof.size,
                    client_final_msg_wo_proof.ptr,
                    ClientProofB64);
        rd_free(ClientProofB64);
        rd_free(client_final_msg_wo_proof.ptr);

        return 0;
}


/**
 * @brief Handle first message from server
 *
 * Parse server response which looks something like:
 * "r=fyko+d2lbbFgONR....,s=QSXCR+Q6sek8bf92,i=4096"
 *
 * @returns -1 on error.
 */
static int
rd_kafka_sasl_scram_handle_server_first_message (rd_kafka_transport_t *rktrans,
                                                 const rd_chariov_t *in,
                                                 rd_chariov_t *out,
                                                 char *errstr,
                                                 size_t errstr_size) {
        struct rd_kafka_sasl_scram_state *state = rktrans->rktrans_sasl.state;
        char *server_nonce;
        rd_chariov_t salt_b64, salt;
        char *itcntstr;
        const char *endptr;
        int itcnt;
        char *attr_m;

        /* Mandatory future extension check */
        if ((attr_m = rd_kafka_sasl_scram_get_attr(
                     in, 'm', NULL, NULL, 0))) {
                rd_snprintf(errstr, errstr_size,
                            "Unsupported mandatory SCRAM extension");
                rd_free(attr_m);
                return -1;
        }

        /* Server nonce */
        if (!(server_nonce = rd_kafka_sasl_scram_get_attr(
                      in, 'r',
                      "Server nonce in server-first-message",
                      errstr, errstr_size)))
                return -1;

        if (strlen(server_nonce) <= state->cnonce.size ||
            strncmp(state->cnonce.ptr, server_nonce, state->cnonce.size)) {
                rd_snprintf(errstr, errstr_size,
                            "Server/client nonce mismatch in "
                            "server-first-message");
                rd_free(server_nonce);
                return -1;
        }

        /* Salt (Base64) */
        if (!(salt_b64.ptr = rd_kafka_sasl_scram_get_attr(
                      in, 's',
                      "Salt in server-first-message",
                      errstr, errstr_size))) {
                rd_free(server_nonce);
                return -1;
        }
        salt_b64.size = strlen(salt_b64.ptr);

        /* Convert Salt to binary */
        if (rd_base64_decode(&salt_b64, &salt) == -1) {
                rd_snprintf(errstr, errstr_size,
                            "Invalid Base64 Salt in server-first-message");
                rd_free(server_nonce);
                rd_free(salt_b64.ptr);
        }
        rd_free(salt_b64.ptr);

        /* Iteration count (as string) */
        if (!(itcntstr = rd_kafka_sasl_scram_get_attr(
                      in, 'i',
                      "Iteration count in server-first-message",
                      errstr, errstr_size))) {
                rd_free(server_nonce);
                rd_free(salt.ptr);
                return -1;
        }

        /* Iteration count (as int) */
        errno = 0;
        itcnt = (int)strtoul(itcntstr, (char **)&endptr, 10);
        if (itcntstr == endptr || *endptr != '\0' || errno != 0 ||
            itcnt > 1000000) {
                rd_snprintf(errstr, errstr_size,
                            "Invalid value (not integer or too large) "
                            "for Iteration count in server-first-message");
                rd_free(server_nonce);
                rd_free(salt.ptr);
                rd_free(itcntstr);
                return -1;
        }
        rd_free(itcntstr);

        /* Build client-final-message */
        if (rd_kafka_sasl_scram_build_client_final_message(
                    rktrans, &salt, server_nonce, in, itcnt, out) == -1) {
                rd_snprintf(errstr, errstr_size,
                            "Failed to build SCRAM client-final-message");
                rd_free(salt.ptr);
                rd_free(server_nonce);
                return -1;
        }

        rd_free(server_nonce);
        rd_free(salt.ptr);

        return 0;
}

/**
 * @brief Handle server-final-message
 * 
 *        This is the end of authentication and the SCRAM state
 *        will be freed at the end of this function regardless of
 *        authentication outcome.
 *
 * @returns -1 on failure
 */
static int
rd_kafka_sasl_scram_handle_server_final_message (
        rd_kafka_transport_t *rktrans,
        const rd_chariov_t *in,
        char *errstr, size_t errstr_size) {
        struct rd_kafka_sasl_scram_state *state = rktrans->rktrans_sasl.state;
        char *attr_v, *attr_e;

        if ((attr_e = rd_kafka_sasl_scram_get_attr(
                            in, 'e', "server-error in server-final-message",
                            errstr, errstr_size))) {
                /* Authentication failed */

                rd_snprintf(errstr, errstr_size,
                            "SASL SCRAM authentication failed: "
                            "broker responded with %s",
                            attr_e);
                rd_free(attr_e);
                return -1;

        } else if ((attr_v = rd_kafka_sasl_scram_get_attr(
                     in, 'v', "verifier in server-final-message",
                     errstr, errstr_size))) {
                const rd_kafka_conf_t *conf;

                /* Authentication succesful on server,
                 * but we need to verify the ServerSignature too. */
                rd_rkb_dbg(rktrans->rktrans_rkb, SECURITY | RD_KAFKA_DBG_BROKER,
                           "SCRAMAUTH",
                           "SASL SCRAM authentication succesful on server: "
                           "verifying ServerSignature");

                if (strcmp(attr_v, state->ServerSignatureB64)) {
                        rd_snprintf(errstr, errstr_size,
                                    "SASL SCRAM authentication failed: "
                                    "ServerSignature mismatch "
                                    "(server's %s != ours %s)",
                                    attr_v, state->ServerSignatureB64);
                        rd_free(attr_v);
                        return -1;
                }
                rd_free(attr_v);

                conf = &rktrans->rktrans_rkb->rkb_rk->rk_conf;

                rd_rkb_dbg(rktrans->rktrans_rkb, SECURITY | RD_KAFKA_DBG_BROKER,
                           "SCRAMAUTH",
                           "Authenticated as %s using %s",
                           conf->sasl.username,
                           conf->sasl.mechanisms);

                rd_kafka_sasl_auth_done(rktrans);
                return 0;

        } else {
                rd_snprintf(errstr, errstr_size,
                            "SASL SCRAM authentication failed: "
                            "no verifier or server-error returned from broker");
                return -1;
        }
}



/**
 * @brief Build client-first-message
 */
static void
rd_kafka_sasl_scram_build_client_first_message (
        rd_kafka_transport_t *rktrans,
        rd_chariov_t *out) {
        char *sasl_username;
        struct rd_kafka_sasl_scram_state *state = rktrans->rktrans_sasl.state;
        const rd_kafka_conf_t *conf = &rktrans->rktrans_rkb->rkb_rk->rk_conf;

        rd_kafka_sasl_scram_generate_nonce(&state->cnonce);

        sasl_username = rd_kafka_sasl_safe_string(conf->sasl.username);

        out->size = strlen("n,,n=,r=") + strlen(sasl_username) +
                state->cnonce.size;
        out->ptr = rd_malloc(out->size+1);

        rd_snprintf(out->ptr, out->size+1,
                    "n,,n=%s,r=%.*s",
                    sasl_username,
                    (int)state->cnonce.size, state->cnonce.ptr);
        rd_free(sasl_username);

        /* Save client-first-message-bare (skip gs2-header) */
        state->first_msg_bare.size = out->size-3;
        state->first_msg_bare.ptr  = rd_memdup(out->ptr+3,
                                               state->first_msg_bare.size);
}



/**
 * @brief SASL SCRAM client state machine
 * @returns -1 on failure (errstr set), else 0.
 */
static int rd_kafka_sasl_scram_fsm (rd_kafka_transport_t *rktrans,
                                    const rd_chariov_t *in,
                                    char *errstr, size_t errstr_size) {
        static const char *state_names[] = {
                "client-first-message",
                "server-first-message",
                "client-final-message",
        };
        struct rd_kafka_sasl_scram_state *state = rktrans->rktrans_sasl.state;
        rd_chariov_t out = RD_ZERO_INIT;
        int r = -1;
        rd_ts_t ts_start = rd_clock();
        int prev_state = state->state;

        rd_rkb_dbg(rktrans->rktrans_rkb, SECURITY, "SASLSCRAM",
                   "SASL SCRAM client in state %s",
                   state_names[state->state]);

        switch (state->state)
        {
        case RD_KAFKA_SASL_SCRAM_STATE_CLIENT_FIRST_MESSAGE:
                rd_dassert(!in); /* Not expecting any server-input */

                rd_kafka_sasl_scram_build_client_first_message(rktrans, &out);
                state->state = RD_KAFKA_SASL_SCRAM_STATE_SERVER_FIRST_MESSAGE;
                break;


        case RD_KAFKA_SASL_SCRAM_STATE_SERVER_FIRST_MESSAGE:
                rd_dassert(in); /* Requires server-input */

                if (rd_kafka_sasl_scram_handle_server_first_message(
                             rktrans, in, &out, errstr, errstr_size) == -1)
                        return -1;

                state->state = RD_KAFKA_SASL_SCRAM_STATE_CLIENT_FINAL_MESSAGE;
                break;

        case RD_KAFKA_SASL_SCRAM_STATE_CLIENT_FINAL_MESSAGE:
                rd_dassert(in);  /* Requires server-input */

                r = rd_kafka_sasl_scram_handle_server_final_message(
                        rktrans, in, errstr, errstr_size);
                break;
        }

        if (out.ptr) {
                r = rd_kafka_sasl_send(rktrans, out.ptr, (int)out.size,
                                       errstr, errstr_size);
                rd_free(out.ptr);
        }

        ts_start = (rd_clock() - ts_start) / 1000;
        if (ts_start >= 100)
                rd_rkb_dbg(rktrans->rktrans_rkb, SECURITY, "SCRAM",
                           "SASL SCRAM state %s handled in %"PRId64"ms",
                           state_names[prev_state], ts_start);


        return r;
}


/**
 * @brief Handle received frame from broker.
 */
static int rd_kafka_sasl_scram_recv (rd_kafka_transport_t *rktrans,
                                     const void *buf, size_t size,
                                     char *errstr, size_t errstr_size) {
        const rd_chariov_t in = { .ptr = (char *)buf, .size = size };
        return rd_kafka_sasl_scram_fsm(rktrans, &in, errstr, errstr_size);
}


/**
 * @brief Initialize and start SASL SCRAM (builtin) authentication.
 *
 * Returns 0 on successful init and -1 on error.
 *
 * @locality broker thread
 */
static int rd_kafka_sasl_scram_client_new (rd_kafka_transport_t *rktrans,
                                    const char *hostname,
                                    char *errstr, size_t errstr_size) {
        struct rd_kafka_sasl_scram_state *state;

        state = rd_calloc(1, sizeof(*state));
        state->state = RD_KAFKA_SASL_SCRAM_STATE_CLIENT_FIRST_MESSAGE;
        rktrans->rktrans_sasl.state = state;

        /* Kick off the FSM */
        return rd_kafka_sasl_scram_fsm(rktrans, NULL, errstr, errstr_size);
}



/**
 * @brief Validate SCRAM config and look up the hash function
 */
static int rd_kafka_sasl_scram_conf_validate (rd_kafka_t *rk,
                                              char *errstr,
                                              size_t errstr_size) {
        const char *mech = rk->rk_conf.sasl.mechanisms;

        if (!rk->rk_conf.sasl.username || !rk->rk_conf.sasl.password) {
                rd_snprintf(errstr, errstr_size,
                            "sasl.username and sasl.password must be set");
                return -1;
        }

        if (!strcmp(mech, "SCRAM-SHA-1")) {
                rk->rk_conf.sasl.scram_evp = EVP_sha1();
                rk->rk_conf.sasl.scram_H = SHA1;
                rk->rk_conf.sasl.scram_H_size = SHA_DIGEST_LENGTH;
        } else if (!strcmp(mech, "SCRAM-SHA-256")) {
                rk->rk_conf.sasl.scram_evp = EVP_sha256();
                rk->rk_conf.sasl.scram_H = SHA256;
                rk->rk_conf.sasl.scram_H_size = SHA256_DIGEST_LENGTH;
        } else if (!strcmp(mech, "SCRAM-SHA-512")) {
                rk->rk_conf.sasl.scram_evp = EVP_sha512();
                rk->rk_conf.sasl.scram_H = SHA512;
                rk->rk_conf.sasl.scram_H_size = SHA512_DIGEST_LENGTH;
        } else {
                rd_snprintf(errstr, errstr_size,
                            "Unsupported hash function: %s "
                            "(try SCRAM-SHA-512)",
                            mech);
                return -1;
        }

        return 0;
}




const struct rd_kafka_sasl_provider rd_kafka_sasl_scram_provider = {
        .name          = "SCRAM (builtin)",
        .client_new    = rd_kafka_sasl_scram_client_new,
        .recv          = rd_kafka_sasl_scram_recv,
        .close         = rd_kafka_sasl_scram_close,
        .conf_validate = rd_kafka_sasl_scram_conf_validate,
};
Ejemplo n.º 23
0
int dgst_main(int argc, char **argv)
{
    BIO *in = NULL, *inp, *bmd = NULL, *out = NULL;
    ENGINE *e = NULL, *impl = NULL;
    EVP_PKEY *sigkey = NULL;
    STACK_OF(OPENSSL_STRING) *sigopts = NULL, *macopts = NULL;
    char *hmac_key = NULL;
    char *mac_name = NULL;
    char *passinarg = NULL, *passin = NULL;
    const EVP_MD *md = NULL, *m;
    const char *outfile = NULL, *keyfile = NULL, *prog = NULL;
    const char *sigfile = NULL, *randfile = NULL;
    OPTION_CHOICE o;
    int separator = 0, debug = 0, keyform = FORMAT_PEM, siglen = 0;
    int i, ret = 1, out_bin = -1, want_pub = 0, do_verify = 0;
    unsigned char *buf = NULL, *sigbuf = NULL;
    int engine_impl = 0;

    prog = opt_progname(argv[0]);
    buf = app_malloc(BUFSIZE, "I/O buffer");
    md = EVP_get_digestbyname(prog);

    prog = opt_init(argc, argv, dgst_options);
    while ((o = opt_next()) != OPT_EOF) {
        switch (o) {
        case OPT_EOF:
        case OPT_ERR:
 opthelp:
            BIO_printf(bio_err, "%s: Use -help for summary.\n", prog);
            goto end;
        case OPT_HELP:
            opt_help(dgst_options);
            ret = 0;
            goto end;
        case OPT_C:
            separator = 1;
            break;
        case OPT_R:
            separator = 2;
            break;
        case OPT_RAND:
            randfile = opt_arg();
            break;
        case OPT_OUT:
            outfile = opt_arg();
            break;
        case OPT_SIGN:
            keyfile = opt_arg();
            break;
        case OPT_PASSIN:
            passinarg = opt_arg();
            break;
        case OPT_VERIFY:
            keyfile = opt_arg();
            want_pub = do_verify = 1;
            break;
        case OPT_PRVERIFY:
            keyfile = opt_arg();
            do_verify = 1;
            break;
        case OPT_SIGNATURE:
            sigfile = opt_arg();
            break;
        case OPT_KEYFORM:
            if (!opt_format(opt_arg(), OPT_FMT_ANY, &keyform))
                goto opthelp;
            break;
        case OPT_ENGINE:
            e = setup_engine(opt_arg(), 0);
            break;
        case OPT_ENGINE_IMPL:
            engine_impl = 1;
            break;
        case OPT_HEX:
            out_bin = 0;
            break;
        case OPT_BINARY:
            out_bin = 1;
            break;
        case OPT_DEBUG:
            debug = 1;
            break;
        case OPT_FIPS_FINGERPRINT:
            hmac_key = "etaonrishdlcupfm";
            break;
        case OPT_HMAC:
            hmac_key = opt_arg();
            break;
        case OPT_MAC:
            mac_name = opt_arg();
            break;
        case OPT_SIGOPT:
            if (!sigopts)
                sigopts = sk_OPENSSL_STRING_new_null();
            if (!sigopts || !sk_OPENSSL_STRING_push(sigopts, opt_arg()))
                goto opthelp;
            break;
        case OPT_MACOPT:
            if (!macopts)
                macopts = sk_OPENSSL_STRING_new_null();
            if (!macopts || !sk_OPENSSL_STRING_push(macopts, opt_arg()))
                goto opthelp;
            break;
        case OPT_DIGEST:
            if (!opt_md(opt_unknown(), &m))
                goto opthelp;
            md = m;
            break;
        }
    }
    argc = opt_num_rest();
    argv = opt_rest();
    if (keyfile != NULL && argc > 1) {
        BIO_printf(bio_err, "%s: Can only sign or verify one file.\n", prog);
        goto end;
    }

    if (do_verify && !sigfile) {
        BIO_printf(bio_err,
                   "No signature to verify: use the -signature option\n");
        goto end;
    }
    if (engine_impl)
        impl = e;

    in = BIO_new(BIO_s_file());
    bmd = BIO_new(BIO_f_md());
    if ((in == NULL) || (bmd == NULL)) {
        ERR_print_errors(bio_err);
        goto end;
    }

    if (debug) {
        BIO_set_callback(in, BIO_debug_callback);
        /* needed for windows 3.1 */
        BIO_set_callback_arg(in, (char *)bio_err);
    }

    if (!app_passwd(passinarg, NULL, &passin, NULL)) {
        BIO_printf(bio_err, "Error getting password\n");
        goto end;
    }

    if (out_bin == -1) {
        if (keyfile)
            out_bin = 1;
        else
            out_bin = 0;
    }

    if (randfile)
        app_RAND_load_file(randfile, 0);

    out = bio_open_default(outfile, 'w', out_bin ? FORMAT_BINARY : FORMAT_TEXT);
    if (out == NULL)
        goto end;

    if ((! !mac_name + ! !keyfile + ! !hmac_key) > 1) {
        BIO_printf(bio_err, "MAC and Signing key cannot both be specified\n");
        goto end;
    }

    if (keyfile) {
        if (want_pub)
            sigkey = load_pubkey(keyfile, keyform, 0, NULL, e, "key file");
        else
            sigkey = load_key(keyfile, keyform, 0, passin, e, "key file");
        if (!sigkey) {
            /*
             * load_[pub]key() has already printed an appropriate message
             */
            goto end;
        }
    }

    if (mac_name) {
        EVP_PKEY_CTX *mac_ctx = NULL;
        int r = 0;
        if (!init_gen_str(&mac_ctx, mac_name, impl, 0))
            goto mac_end;
        if (macopts) {
            char *macopt;
            for (i = 0; i < sk_OPENSSL_STRING_num(macopts); i++) {
                macopt = sk_OPENSSL_STRING_value(macopts, i);
                if (pkey_ctrl_string(mac_ctx, macopt) <= 0) {
                    BIO_printf(bio_err,
                               "MAC parameter error \"%s\"\n", macopt);
                    ERR_print_errors(bio_err);
                    goto mac_end;
                }
            }
        }
        if (EVP_PKEY_keygen(mac_ctx, &sigkey) <= 0) {
            BIO_puts(bio_err, "Error generating key\n");
            ERR_print_errors(bio_err);
            goto mac_end;
        }
        r = 1;
 mac_end:
        EVP_PKEY_CTX_free(mac_ctx);
        if (r == 0)
            goto end;
    }

    if (hmac_key) {
        sigkey = EVP_PKEY_new_mac_key(EVP_PKEY_HMAC, impl,
                                      (unsigned char *)hmac_key, -1);
        if (!sigkey)
            goto end;
    }

    if (sigkey) {
        EVP_MD_CTX *mctx = NULL;
        EVP_PKEY_CTX *pctx = NULL;
        int r;
        if (!BIO_get_md_ctx(bmd, &mctx)) {
            BIO_printf(bio_err, "Error getting context\n");
            ERR_print_errors(bio_err);
            goto end;
        }
        if (do_verify)
            r = EVP_DigestVerifyInit(mctx, &pctx, md, impl, sigkey);
        else
            r = EVP_DigestSignInit(mctx, &pctx, md, impl, sigkey);
        if (!r) {
            BIO_printf(bio_err, "Error setting context\n");
            ERR_print_errors(bio_err);
            goto end;
        }
        if (sigopts) {
            char *sigopt;
            for (i = 0; i < sk_OPENSSL_STRING_num(sigopts); i++) {
                sigopt = sk_OPENSSL_STRING_value(sigopts, i);
                if (pkey_ctrl_string(pctx, sigopt) <= 0) {
                    BIO_printf(bio_err, "parameter error \"%s\"\n", sigopt);
                    ERR_print_errors(bio_err);
                    goto end;
                }
            }
        }
    }
    /* we use md as a filter, reading from 'in' */
    else {
        EVP_MD_CTX *mctx = NULL;
        if (!BIO_get_md_ctx(bmd, &mctx)) {
            BIO_printf(bio_err, "Error getting context\n");
            ERR_print_errors(bio_err);
            goto end;
        }
        if (md == NULL)
            md = EVP_sha256();
        if (!EVP_DigestInit_ex(mctx, md, impl)) {
            BIO_printf(bio_err, "Error setting digest\n");
            ERR_print_errors(bio_err);
            goto end;
        }
    }

    if (sigfile && sigkey) {
        BIO *sigbio = BIO_new_file(sigfile, "rb");
        if (!sigbio) {
            BIO_printf(bio_err, "Error opening signature file %s\n", sigfile);
            ERR_print_errors(bio_err);
            goto end;
        }
        siglen = EVP_PKEY_size(sigkey);
        sigbuf = app_malloc(siglen, "signature buffer");
        siglen = BIO_read(sigbio, sigbuf, siglen);
        BIO_free(sigbio);
        if (siglen <= 0) {
            BIO_printf(bio_err, "Error reading signature file %s\n", sigfile);
            ERR_print_errors(bio_err);
            goto end;
        }
    }
    inp = BIO_push(bmd, in);

    if (md == NULL) {
        EVP_MD_CTX *tctx;
        BIO_get_md_ctx(bmd, &tctx);
        md = EVP_MD_CTX_md(tctx);
    }

    if (argc == 0) {
        BIO_set_fp(in, stdin, BIO_NOCLOSE);
        ret = do_fp(out, buf, inp, separator, out_bin, sigkey, sigbuf,
                    siglen, NULL, NULL, "stdin");
    } else {
        const char *md_name = NULL, *sig_name = NULL;
        if (!out_bin) {
            if (sigkey) {
                const EVP_PKEY_ASN1_METHOD *ameth;
                ameth = EVP_PKEY_get0_asn1(sigkey);
                if (ameth)
                    EVP_PKEY_asn1_get0_info(NULL, NULL,
                                            NULL, NULL, &sig_name, ameth);
            }
            if (md)
                md_name = EVP_MD_name(md);
        }
        ret = 0;
        for (i = 0; i < argc; i++) {
            int r;
            if (BIO_read_filename(in, argv[i]) <= 0) {
                perror(argv[i]);
                ret++;
                continue;
            } else
                r = do_fp(out, buf, inp, separator, out_bin, sigkey, sigbuf,
                          siglen, sig_name, md_name, argv[i]);
            if (r)
                ret = r;
            (void)BIO_reset(bmd);
        }
    }
 end:
    OPENSSL_clear_free(buf, BUFSIZE);
    BIO_free(in);
    OPENSSL_free(passin);
    BIO_free_all(out);
    EVP_PKEY_free(sigkey);
    sk_OPENSSL_STRING_free(sigopts);
    sk_OPENSSL_STRING_free(macopts);
    OPENSSL_free(sigbuf);
    BIO_free(bmd);
    release_engine(e);
    return (ret);
}
Ejemplo n.º 24
0
const EVP_MD *ssl_handshake_md(SSL *s)
{
    return EVP_sha256();
}
Ejemplo n.º 25
0
static int 
xmlSecOpenSSLEvpDigestInitialize(xmlSecTransformPtr transform) {
    xmlSecOpenSSLDigestCtxPtr ctx;
    
    xmlSecAssert2(xmlSecOpenSSLEvpDigestCheckId(transform), -1);
    xmlSecAssert2(xmlSecTransformCheckSize(transform, xmlSecOpenSSLEvpDigestSize), -1);

    ctx = xmlSecOpenSSLEvpDigestGetCtx(transform);
    xmlSecAssert2(ctx != NULL, -1);

    /* initialize context */
    memset(ctx, 0, sizeof(xmlSecOpenSSLDigestCtx));

#ifndef XMLSEC_NO_MD5
    if(xmlSecTransformCheckId(transform, xmlSecOpenSSLTransformMd5Id)) {
        ctx->digest = EVP_md5();
    } else 
#endif /* XMLSEC_NO_MD5 */
    
#ifndef XMLSEC_NO_RIPEMD160 
    if(xmlSecTransformCheckId(transform, xmlSecOpenSSLTransformRipemd160Id)) {
        ctx->digest = EVP_ripemd160();
    } else 
#endif /* XMLSEC_NO_RIPEMD160 */
    
#ifndef XMLSEC_NO_SHA1
    if(xmlSecTransformCheckId(transform, xmlSecOpenSSLTransformSha1Id)) {
        ctx->digest = EVP_sha1();
    } else 
#endif /* XMLSEC_NO_SHA1 */    

#ifndef XMLSEC_NO_SHA224
    if(xmlSecTransformCheckId(transform, xmlSecOpenSSLTransformSha224Id)) {
        ctx->digest = EVP_sha224();
    } else 
#endif /* XMLSEC_NO_SHA224 */    

#ifndef XMLSEC_NO_SHA256
    if(xmlSecTransformCheckId(transform, xmlSecOpenSSLTransformSha256Id)) {
        ctx->digest = EVP_sha256();
    } else 
#endif /* XMLSEC_NO_SHA256 */    
    
#ifndef XMLSEC_NO_SHA384
    if(xmlSecTransformCheckId(transform, xmlSecOpenSSLTransformSha384Id)) {
        ctx->digest = EVP_sha384();
    } else 
#endif /* XMLSEC_NO_SHA384 */    

#ifndef XMLSEC_NO_SHA512
    if(xmlSecTransformCheckId(transform, xmlSecOpenSSLTransformSha512Id)) {
        ctx->digest = EVP_sha512();
    } else 
#endif /* XMLSEC_NO_SHA512 */    

    {
	xmlSecErr_a_ignorar5(XMLSEC_ERRORS_HERE, 
		    xmlSecErrorsSafeString(xmlSecTransformGetName(transform)),
		    NULL,
		    XMLSEC_ERRORS_R_INVALID_TRANSFORM,
		    XMLSEC_ERRORS_NO_MESSAGE);
	return(-1);
    }

#ifndef XMLSEC_OPENSSL_096
    EVP_MD_CTX_init(&(ctx->digestCtx));
#endif /* XMLSEC_OPENSSL_096 */
    
    return(0);
}
Ejemplo n.º 26
0
const EVP_MD *ssl_md(int idx)
{
    return EVP_sha256();
}
Ejemplo n.º 27
0
void janus_dtls_srtp_incoming_msg(janus_dtls_srtp *dtls, char *buf, uint16_t len) {
	if(dtls == NULL) {
		JANUS_LOG(LOG_ERR, "No DTLS-SRTP stack, no incoming message...\n");
		return;
	}
	janus_ice_component *component = (janus_ice_component *)dtls->component;
	if(component == NULL) {
		JANUS_LOG(LOG_ERR, "No component, no DTLS...\n");
		return;
	}
	janus_ice_stream *stream = component->stream;
	if(!stream) {
		JANUS_LOG(LOG_ERR, "No stream, no DTLS...\n");
		return;
	}
	janus_ice_handle *handle = stream->handle;
	if(!handle || !handle->agent) {
		JANUS_LOG(LOG_ERR, "No handle/agent, no DTLS...\n");
		return;
	}
	if(janus_flags_is_set(&handle->webrtc_flags, JANUS_ICE_HANDLE_WEBRTC_ALERT)) {
		JANUS_LOG(LOG_ERR, "Alert already received, clearing up...\n");
		return;
	}
	if(!dtls->ssl || !dtls->read_bio) {
		JANUS_LOG(LOG_ERR, "[%"SCNu64"] No DTLS stuff for component %d in stream %d??\n", handle->handle_id, component->component_id, stream->stream_id);
		return;
	}
	/* We just got a message, can we get rid of the last sent message? */
	if(dtls->dtls_last_msg != NULL) {
		g_free(dtls->dtls_last_msg);
		dtls->dtls_last_msg = NULL;
		dtls->dtls_last_len = 0;
	}
	janus_dtls_fd_bridge(dtls);
	int written = BIO_write(dtls->read_bio, buf, len);
	JANUS_LOG(LOG_HUGE, "    Written %d of those bytes on the read BIO...\n", written);
	janus_dtls_fd_bridge(dtls);
	int read = SSL_read(dtls->ssl, buf, len);
	JANUS_LOG(LOG_HUGE, "    ...and read %d of them from SSL...\n", read);
	janus_dtls_fd_bridge(dtls);
	if(janus_flags_is_set(&handle->webrtc_flags, JANUS_ICE_HANDLE_WEBRTC_STOP) || janus_is_stopping()) {
		/* DTLS alert received, we should end it here */
		JANUS_LOG(LOG_VERB, "[%"SCNu64"] Forced to stop it here...\n", handle->handle_id);
		return;
	}
	if(SSL_is_init_finished(dtls->ssl)) {
		JANUS_LOG(LOG_VERB, "[%"SCNu64"] DTLS established, yay!\n", handle->handle_id);
		/* Check the remote fingerprint */
		X509 *rcert = SSL_get_peer_certificate(dtls->ssl);
		if(!rcert) {
			JANUS_LOG(LOG_ERR, "[%"SCNu64"] No remote certificate??\n", handle->handle_id);
		} else {
			unsigned int rsize;
			unsigned char rfingerprint[EVP_MAX_MD_SIZE];
			char remote_fingerprint[160];
			char *rfp = (char *)&remote_fingerprint;
			if(handle->remote_hashing && !strcasecmp(handle->remote_hashing, "sha-1")) {
				JANUS_LOG(LOG_VERB, "[%"SCNu64"] Computing sha-1 fingerprint of remote certificate...\n", handle->handle_id);
				X509_digest(rcert, EVP_sha1(), (unsigned char *)rfingerprint, &rsize);
			} else {
				JANUS_LOG(LOG_VERB, "[%"SCNu64"] Computing sha-256 fingerprint of remote certificate...\n", handle->handle_id);
				X509_digest(rcert, EVP_sha256(), (unsigned char *)rfingerprint, &rsize);
			}
			X509_free(rcert);
			rcert = NULL;
			int i = 0;
			for(i = 0; i < rsize; i++) {
				sprintf(rfp, "%.2X:", rfingerprint[i]);
				rfp += 3;
			}
			*(rfp-1) = 0;
			JANUS_LOG(LOG_VERB, "[%"SCNu64"] Remote fingerprint (%s) of the client is %s\n",
				handle->handle_id, handle->remote_hashing ? handle->remote_hashing : "sha-256", remote_fingerprint);
			if(!strcasecmp(remote_fingerprint, handle->remote_fingerprint ? handle->remote_fingerprint : "(none)")) {
				JANUS_LOG(LOG_VERB, "[%"SCNu64"]  Fingerprint is a match!\n", handle->handle_id);
				dtls->dtls_state = JANUS_DTLS_STATE_CONNECTED;
			} else {
				/* FIXME NOT a match! MITM? */
				JANUS_LOG(LOG_ERR, "[%"SCNu64"]  Fingerprint is NOT a match! expected %s\n", handle->handle_id, handle->remote_fingerprint);
				dtls->dtls_state = JANUS_DTLS_STATE_FAILED;
				goto done;
			}
			if(dtls->dtls_state == JANUS_DTLS_STATE_CONNECTED) {
				/* Complete with SRTP setup */
				unsigned char material[SRTP_MASTER_LENGTH*2];
				unsigned char *local_key, *local_salt, *remote_key, *remote_salt;
				/* Export keying material for SRTP */
				if (!SSL_export_keying_material(dtls->ssl, material, SRTP_MASTER_LENGTH*2, "EXTRACTOR-dtls_srtp", 19, NULL, 0, 0)) {
					/* Oops... */
					JANUS_LOG(LOG_ERR, "[%"SCNu64"] Oops, couldn't extract SRTP keying material for component %d in stream %d??\n", handle->handle_id, component->component_id, stream->stream_id);
					goto done;
				}
				/* Key derivation (http://tools.ietf.org/html/rfc5764#section-4.2) */
				if(dtls->dtls_role == JANUS_DTLS_ROLE_CLIENT) {
					local_key = material;
					remote_key = local_key + SRTP_MASTER_KEY_LENGTH;
					local_salt = remote_key + SRTP_MASTER_KEY_LENGTH;
					remote_salt = local_salt + SRTP_MASTER_SALT_LENGTH;
				} else {
					remote_key = material;
					local_key = remote_key + SRTP_MASTER_KEY_LENGTH;
					remote_salt = local_key + SRTP_MASTER_KEY_LENGTH;
					local_salt = remote_salt + SRTP_MASTER_SALT_LENGTH;
				}
				/* Build master keys and set SRTP policies */
					/* Remote (inbound) */
				crypto_policy_set_rtp_default(&(dtls->remote_policy.rtp));
				crypto_policy_set_rtcp_default(&(dtls->remote_policy.rtcp));
				dtls->remote_policy.ssrc.type = ssrc_any_inbound;
				dtls->remote_policy.key = calloc(SRTP_MASTER_LENGTH+8, sizeof(char));
				if(dtls->remote_policy.key == NULL) {
					JANUS_LOG(LOG_FATAL, "Memory error!\n");
					goto done;
				}
				memcpy(dtls->remote_policy.key, remote_key, SRTP_MASTER_KEY_LENGTH);
				memcpy(dtls->remote_policy.key + SRTP_MASTER_KEY_LENGTH, remote_salt, SRTP_MASTER_SALT_LENGTH);
				dtls->remote_policy.window_size = 128;
				dtls->remote_policy.allow_repeat_tx = 0;
				dtls->remote_policy.next = NULL;
					/* Local (outbound) */
				crypto_policy_set_rtp_default(&(dtls->local_policy.rtp));
				crypto_policy_set_rtcp_default(&(dtls->local_policy.rtcp));
				dtls->local_policy.ssrc.type = ssrc_any_outbound;
				dtls->local_policy.key = calloc(SRTP_MASTER_LENGTH+8, sizeof(char));
				if(dtls->local_policy.key == NULL) {
					JANUS_LOG(LOG_FATAL, "Memory error!\n");
					goto done;
				}
				memcpy(dtls->local_policy.key, local_key, SRTP_MASTER_KEY_LENGTH);
				memcpy(dtls->local_policy.key + SRTP_MASTER_KEY_LENGTH, local_salt, SRTP_MASTER_SALT_LENGTH);
				dtls->local_policy.window_size = 128;
				dtls->local_policy.allow_repeat_tx = 0;
				dtls->local_policy.next = NULL;
				/* Create SRTP sessions */
				err_status_t res = srtp_create(&(dtls->srtp_in), &(dtls->remote_policy));
				if(res != err_status_ok) {
					/* Something went wrong... */
					JANUS_LOG(LOG_ERR, "[%"SCNu64"] Oops, error creating inbound SRTP session for component %d in stream %d??\n", handle->handle_id, component->component_id, stream->stream_id);
					JANUS_LOG(LOG_ERR, "[%"SCNu64"]  -- %d (%s)\n", handle->handle_id, res, janus_get_srtp_error(res));
					goto done;
				}
				JANUS_LOG(LOG_VERB, "[%"SCNu64"] Created inbound SRTP session for component %d in stream %d\n", handle->handle_id, component->component_id, stream->stream_id);
				res = srtp_create(&(dtls->srtp_out), &(dtls->local_policy));
				if(res != err_status_ok) {
					/* Something went wrong... */
					JANUS_LOG(LOG_ERR, "[%"SCNu64"] Oops, error creating outbound SRTP session for component %d in stream %d??\n", handle->handle_id, component->component_id, stream->stream_id);
					JANUS_LOG(LOG_ERR, "[%"SCNu64"]  -- %d (%s)\n", handle->handle_id, res, janus_get_srtp_error(res));
					goto done;
				}
				dtls->srtp_valid = 1;
				JANUS_LOG(LOG_VERB, "[%"SCNu64"] Created outbound SRTP session for component %d in stream %d\n", handle->handle_id, component->component_id, stream->stream_id);
			}
done:
			if(!janus_flags_is_set(&handle->webrtc_flags, JANUS_ICE_HANDLE_WEBRTC_ALERT) && dtls->srtp_valid) {
				/* Handshake successfully completed */
				janus_ice_dtls_handshake_done(handle, component);
			} else {
				/* Something went wrong in either DTLS or SRTP... tell the plugin about it */
				janus_dtls_callback(dtls->ssl, SSL_CB_ALERT, 0);
			}
		}
	}
}
Ejemplo n.º 28
0
int main(int argc, char **argv)
{
    unsigned char md[SHA256_DIGEST_LENGTH];
    int i;
    EVP_MD_CTX evp;

    fprintf(stdout, "Testing SHA-256 ");

    EVP_Digest("abc", 3, md, NULL, EVP_sha256(), NULL);
    if (sgx_memcmp(md, app_b1, sizeof(app_b1))) {
        fflush(stdout);
        fprintf(stderr, "\nTEST 1 of 3 failed.\n");
        return 1;
    } else
        fprintf(stdout, ".");
    fflush(stdout);

    EVP_Digest("abcdbcde" "cdefdefg" "efghfghi" "ghijhijk"
               "ijkljklm" "klmnlmno" "mnopnopq", 56, md, NULL, EVP_sha256(),
               NULL);
    if (sgx_memcmp(md, app_b2, sizeof(app_b2))) {
        fflush(stdout);
        fprintf(stderr, "\nTEST 2 of 3 failed.\n");
        return 1;
    } else
        fprintf(stdout, ".");
    fflush(stdout);

    EVP_MD_CTX_init(&evp);
    EVP_DigestInit_ex(&evp, EVP_sha256(), NULL);
    for (i = 0; i < 1000000; i += 160)
        EVP_DigestUpdate(&evp, "aaaaaaaa" "aaaaaaaa" "aaaaaaaa" "aaaaaaaa"
                         "aaaaaaaa" "aaaaaaaa" "aaaaaaaa" "aaaaaaaa"
                         "aaaaaaaa" "aaaaaaaa" "aaaaaaaa" "aaaaaaaa"
                         "aaaaaaaa" "aaaaaaaa" "aaaaaaaa" "aaaaaaaa"
                         "aaaaaaaa" "aaaaaaaa" "aaaaaaaa" "aaaaaaaa",
                         (1000000 - i) < 160 ? 1000000 - i : 160);
    EVP_DigestFinal_ex(&evp, md, NULL);
    EVP_MD_CTX_cleanup(&evp);

    if (sgx_memcmp(md, app_b3, sizeof(app_b3))) {
        fflush(stdout);
        fprintf(stderr, "\nTEST 3 of 3 failed.\n");
        return 1;
    } else
        fprintf(stdout, ".");
    fflush(stdout);

    fprintf(stdout, " passed.\n");
    fflush(stdout);

    fprintf(stdout, "Testing SHA-224 ");

    EVP_Digest("abc", 3, md, NULL, EVP_sha224(), NULL);
    if (sgx_memcmp(md, addenum_1, sizeof(addenum_1))) {
        fflush(stdout);
        fprintf(stderr, "\nTEST 1 of 3 failed.\n");
        return 1;
    } else
        fprintf(stdout, ".");
    fflush(stdout);

    EVP_Digest("abcdbcde" "cdefdefg" "efghfghi" "ghijhijk"
               "ijkljklm" "klmnlmno" "mnopnopq", 56, md, NULL, EVP_sha224(),
               NULL);
    if (sgx_memcmp(md, addenum_2, sizeof(addenum_2))) {
        fflush(stdout);
        fprintf(stderr, "\nTEST 2 of 3 failed.\n");
        return 1;
    } else
        fprintf(stdout, ".");
    fflush(stdout);

    EVP_MD_CTX_init(&evp);
    EVP_DigestInit_ex(&evp, EVP_sha224(), NULL);
    for (i = 0; i < 1000000; i += 64)
        EVP_DigestUpdate(&evp, "aaaaaaaa" "aaaaaaaa" "aaaaaaaa" "aaaaaaaa"
                         "aaaaaaaa" "aaaaaaaa" "aaaaaaaa" "aaaaaaaa",
                         (1000000 - i) < 64 ? 1000000 - i : 64);
    EVP_DigestFinal_ex(&evp, md, NULL);
    EVP_MD_CTX_cleanup(&evp);

    if (sgx_memcmp(md, addenum_3, sizeof(addenum_3))) {
        fflush(stdout);
        fprintf(stderr, "\nTEST 3 of 3 failed.\n");
        return 1;
    } else
        fprintf(stdout, ".");
    fflush(stdout);

    fprintf(stdout, " passed.\n");
    fflush(stdout);

    return 0;
}
Ejemplo n.º 29
0
Archivo: jws.c Proyecto: cisco/cjose
static bool _cjose_jws_build_dig_sha(cjose_jws_t *jws, const cjose_jwk_t *jwk, cjose_err *err)
{
    bool retval = false;
    EVP_MD_CTX *ctx = NULL;

    // make sure we have an alg header
    json_t *alg_obj = json_object_get(jws->hdr, CJOSE_HDR_ALG);
    if (NULL == alg_obj)
    {
        CJOSE_ERROR(err, CJOSE_ERR_INVALID_ARG);
        return false;
    }
    const char *alg = json_string_value(alg_obj);

    // build digest using SHA-256/384/512 digest algorithm
    const EVP_MD *digest_alg = NULL;
    if ((strcmp(alg, CJOSE_HDR_ALG_RS256) == 0) || (strcmp(alg, CJOSE_HDR_ALG_PS256) == 0)
        || (strcmp(alg, CJOSE_HDR_ALG_ES256) == 0))
        digest_alg = EVP_sha256();
    else if ((strcmp(alg, CJOSE_HDR_ALG_RS384) == 0) || (strcmp(alg, CJOSE_HDR_ALG_PS384) == 0)
             || (strcmp(alg, CJOSE_HDR_ALG_ES384) == 0))
        digest_alg = EVP_sha384();
    else if ((strcmp(alg, CJOSE_HDR_ALG_RS512) == 0) || (strcmp(alg, CJOSE_HDR_ALG_PS512) == 0)
             || (strcmp(alg, CJOSE_HDR_ALG_ES512) == 0))
        digest_alg = EVP_sha512();

    if (NULL == digest_alg)
    {
        CJOSE_ERROR(err, CJOSE_ERR_CRYPTO);
        goto _cjose_jws_build_dig_sha_cleanup;
    }

    if (NULL != jws->dig)
    {
    	cjose_get_dealloc()(jws->dig);
    	jws->dig = NULL;
    }

    // allocate buffer for digest
    jws->dig_len = EVP_MD_size(digest_alg);
    jws->dig = (uint8_t *)cjose_get_alloc()(jws->dig_len);
    if (NULL == jws->dig)
    {
        CJOSE_ERROR(err, CJOSE_ERR_NO_MEMORY);
        goto _cjose_jws_build_dig_sha_cleanup;
    }

    // instantiate and initialize a new mac digest context
    ctx = EVP_MD_CTX_create();
    if (NULL == ctx)
    {
        CJOSE_ERROR(err, CJOSE_ERR_CRYPTO);
        goto _cjose_jws_build_dig_sha_cleanup;
    }
    EVP_MD_CTX_init(ctx);

    // create digest as DIGEST(B64U(HEADER).B64U(DATA))
    if (EVP_DigestInit_ex(ctx, digest_alg, NULL) != 1)
    {
        CJOSE_ERROR(err, CJOSE_ERR_CRYPTO);
        goto _cjose_jws_build_dig_sha_cleanup;
    }
    if (EVP_DigestUpdate(ctx, jws->hdr_b64u, jws->hdr_b64u_len) != 1)
    {
        CJOSE_ERROR(err, CJOSE_ERR_CRYPTO);
        goto _cjose_jws_build_dig_sha_cleanup;
    }
    if (EVP_DigestUpdate(ctx, ".", 1) != 1)
    {
        CJOSE_ERROR(err, CJOSE_ERR_CRYPTO);
        goto _cjose_jws_build_dig_sha_cleanup;
    }
    if (EVP_DigestUpdate(ctx, jws->dat_b64u, jws->dat_b64u_len) != 1)
    {
        CJOSE_ERROR(err, CJOSE_ERR_CRYPTO);
        goto _cjose_jws_build_dig_sha_cleanup;
    }
    if (EVP_DigestFinal_ex(ctx, jws->dig, NULL) != 1)
    {
        CJOSE_ERROR(err, CJOSE_ERR_CRYPTO);
        goto _cjose_jws_build_dig_sha_cleanup;
    }

    // if we got this far - success
    retval = true;

_cjose_jws_build_dig_sha_cleanup:
    if (NULL != ctx)
    {
        EVP_MD_CTX_destroy(ctx);
    }

    return retval;
}
Ejemplo n.º 30
0
int
TLSTicketKeyManager::processTicket(SSL* ssl, unsigned char* keyName,
                                   unsigned char* iv,
                                   EVP_CIPHER_CTX* cipherCtx,
                                   HMAC_CTX* hmacCtx, int encrypt) {
  uint8_t salt[kTLSTicketKeySaltLen];
  uint8_t* saltptr = nullptr;
  uint8_t output[SHA256_DIGEST_LENGTH];
  uint8_t* hmacKey = nullptr;
  uint8_t* aesKey = nullptr;
  TLSTicketKeySource* key = nullptr;
  int result = 0;

  if (encrypt) {
    key = findEncryptionKey();
    if (key == nullptr) {
      // no keys available to encrypt
      VLOG(2) << "No TLS ticket key found";
      return -1;
    }
    VLOG(4) << "Encrypting new ticket with key name=" <<
      SSLUtil::hexlify(key->keyName_);

    // Get a random salt and write out key name
    RAND_pseudo_bytes(salt, (int)sizeof(salt));
    memcpy(keyName, key->keyName_.data(), kTLSTicketKeyNameLen);
    memcpy(keyName + kTLSTicketKeyNameLen, salt, kTLSTicketKeySaltLen);

    // Create the unique keys by hashing with the salt
    makeUniqueKeys(key->keySource_, sizeof(key->keySource_), salt, output);
    // This relies on the fact that SHA256 has 32 bytes of output
    // and that AES-128 keys are 16 bytes
    hmacKey = output;
    aesKey = output + SHA256_DIGEST_LENGTH / 2;

    // Initialize iv and cipher/mac CTX
    RAND_pseudo_bytes(iv, AES_BLOCK_SIZE);
    HMAC_Init_ex(hmacCtx, hmacKey, SHA256_DIGEST_LENGTH / 2,
                 EVP_sha256(), nullptr);
    EVP_EncryptInit_ex(cipherCtx, EVP_aes_128_cbc(), nullptr, aesKey, iv);

    result = 1;
  } else {
    key = findDecryptionKey(keyName);
    if (key == nullptr) {
      // no ticket found for decryption - will issue a new ticket
      if (VLOG_IS_ON(4)) {
        string skeyName((char *)keyName, kTLSTicketKeyNameLen);
        VLOG(4) << "Can't find ticket key with name=" <<
          SSLUtil::hexlify(skeyName)<< ", will generate new ticket";
      }

      result = 0;
    } else {
      VLOG(4) << "Decrypting ticket with key name=" <<
        SSLUtil::hexlify(key->keyName_);

      // Reconstruct the unique key via the salt
      saltptr = keyName + kTLSTicketKeyNameLen;
      makeUniqueKeys(key->keySource_, sizeof(key->keySource_), saltptr, output);
      hmacKey = output;
      aesKey = output + SHA256_DIGEST_LENGTH / 2;

      // Initialize cipher/mac CTX
      HMAC_Init_ex(hmacCtx, hmacKey, SHA256_DIGEST_LENGTH / 2,
                   EVP_sha256(), nullptr);
      EVP_DecryptInit_ex(cipherCtx, EVP_aes_128_cbc(), nullptr, aesKey, iv);

      result = 1;
    }
  }
  // result records whether a ticket key was found to decrypt this ticket,
  // not wether the session was re-used.
  if (stats_) {
    stats_->recordTLSTicket(encrypt, result);
  }

  return result;
}