Пример #1
0
BIO *PKCS7_dataInit(PKCS7 *p7, BIO *bio)
	{
	int i,j;
	BIO *out=NULL,*btmp=NULL;
	X509_ALGOR *xa;
	const EVP_MD *evp_md;
	const EVP_CIPHER *evp_cipher=NULL;
	STACK_OF(X509_ALGOR) *md_sk=NULL;
	STACK_OF(PKCS7_RECIP_INFO) *rsk=NULL;
	X509_ALGOR *xalg=NULL;
	PKCS7_RECIP_INFO *ri=NULL;
	EVP_PKEY *pkey;

	i=OBJ_obj2nid(p7->type);
	p7->state=PKCS7_S_HEADER;

	switch (i)
		{
	case NID_pkcs7_signed:
		md_sk=p7->d.sign->md_algs;
		break;
	case NID_pkcs7_signedAndEnveloped:
		rsk=p7->d.signed_and_enveloped->recipientinfo;
		md_sk=p7->d.signed_and_enveloped->md_algs;
		xalg=p7->d.signed_and_enveloped->enc_data->algorithm;
		evp_cipher=p7->d.signed_and_enveloped->enc_data->cipher;
		if (evp_cipher == NULL)
			{
			PKCS7err(PKCS7_F_PKCS7_DATAINIT,
						PKCS7_R_CIPHER_NOT_INITIALIZED);
			goto err;
			}
		break;
	case NID_pkcs7_enveloped:
		rsk=p7->d.enveloped->recipientinfo;
		xalg=p7->d.enveloped->enc_data->algorithm;
		evp_cipher=p7->d.enveloped->enc_data->cipher;
		if (evp_cipher == NULL)
			{
			PKCS7err(PKCS7_F_PKCS7_DATAINIT,
						PKCS7_R_CIPHER_NOT_INITIALIZED);
			goto err;
			}
		break;
	default:
		PKCS7err(PKCS7_F_PKCS7_DATAINIT,PKCS7_R_UNSUPPORTED_CONTENT_TYPE);
	        goto err;
		}

	if (md_sk != NULL)
		{
		for (i=0; i<sk_X509_ALGOR_num(md_sk); i++)
			{
			xa=sk_X509_ALGOR_value(md_sk,i);
			if ((btmp=BIO_new(BIO_f_md())) == NULL)
				{
				PKCS7err(PKCS7_F_PKCS7_DATAINIT,ERR_R_BIO_LIB);
				goto err;
				}

			j=OBJ_obj2nid(xa->algorithm);
			evp_md=EVP_get_digestbyname(OBJ_nid2sn(j));
			if (evp_md == NULL)
				{
				PKCS7err(PKCS7_F_PKCS7_DATAINIT,PKCS7_R_UNKNOWN_DIGEST_TYPE);
				goto err;
				}

			BIO_set_md(btmp,evp_md);
			if (out == NULL)
				out=btmp;
			else
				BIO_push(out,btmp);
			btmp=NULL;
			}
		}

	if (evp_cipher != NULL)
		{
		unsigned char key[EVP_MAX_KEY_LENGTH];
		unsigned char iv[EVP_MAX_IV_LENGTH];
		int keylen,ivlen;
		int jj,max;
		unsigned char *tmp;
		EVP_CIPHER_CTX *ctx;

		if ((btmp=BIO_new(BIO_f_cipher())) == NULL)
			{
			PKCS7err(PKCS7_F_PKCS7_DATAINIT,ERR_R_BIO_LIB);
			goto err;
			}
		BIO_get_cipher_ctx(btmp, &ctx);
		keylen=EVP_CIPHER_key_length(evp_cipher);
		ivlen=EVP_CIPHER_iv_length(evp_cipher);
		if (RAND_bytes(key,keylen) <= 0)
			goto err;
		xalg->algorithm = OBJ_nid2obj(EVP_CIPHER_type(evp_cipher));
		if (ivlen > 0) RAND_pseudo_bytes(iv,ivlen);
		EVP_CipherInit_ex(ctx, evp_cipher, NULL, key, iv, 1);

		if (ivlen > 0) {
			if (xalg->parameter == NULL) 
						xalg->parameter=ASN1_TYPE_new();
			if(EVP_CIPHER_param_to_asn1(ctx, xalg->parameter) < 0)
								       goto err;
		}

		/* Lets do the pub key stuff :-) */
		max=0;
		for (i=0; i<sk_PKCS7_RECIP_INFO_num(rsk); i++)
			{
			ri=sk_PKCS7_RECIP_INFO_value(rsk,i);
			if (ri->cert == NULL)
				{
				PKCS7err(PKCS7_F_PKCS7_DATAINIT,PKCS7_R_MISSING_CERIPEND_INFO);
				goto err;
				}
			pkey=X509_get_pubkey(ri->cert);
			jj=EVP_PKEY_size(pkey);
			EVP_PKEY_free(pkey);
			if (max < jj) max=jj;
			}
		if ((tmp=(unsigned char *)OPENSSL_malloc(max)) == NULL)
			{
			PKCS7err(PKCS7_F_PKCS7_DATAINIT,ERR_R_MALLOC_FAILURE);
			goto err;
			}
		for (i=0; i<sk_PKCS7_RECIP_INFO_num(rsk); i++)
			{
			ri=sk_PKCS7_RECIP_INFO_value(rsk,i);
			pkey=X509_get_pubkey(ri->cert);
			jj=EVP_PKEY_encrypt(tmp,key,keylen,pkey);
			EVP_PKEY_free(pkey);
			if (jj <= 0)
				{
				PKCS7err(PKCS7_F_PKCS7_DATAINIT,ERR_R_EVP_LIB);
				OPENSSL_free(tmp);
				goto err;
				}
			M_ASN1_OCTET_STRING_set(ri->enc_key,tmp,jj);
			}
		OPENSSL_free(tmp);
		OPENSSL_cleanse(key, keylen);

		if (out == NULL)
			out=btmp;
		else
			BIO_push(out,btmp);
		btmp=NULL;
		}

	if (bio == NULL) {
		if (PKCS7_is_detached(p7))
			bio=BIO_new(BIO_s_null());
		else {
			if (PKCS7_type_is_signed(p7) ) { 
				if ( PKCS7_type_is_data(p7->d.sign->contents)) {
					ASN1_OCTET_STRING *os;
					os=p7->d.sign->contents->d.data;
					if (os->length > 0)
						bio = BIO_new_mem_buf(os->data, os->length);
				}
				else if ( PKCS7_type_is_octet_string(p7->d.sign->contents) ) {
					ASN1_OCTET_STRING *os;
					os=p7->d.sign->contents->d.other->value.octet_string;
					if (os->length > 0)
						bio = BIO_new_mem_buf(os->data, os->length);
				}
			}
			if(bio == NULL) {
				bio=BIO_new(BIO_s_mem());
				BIO_set_mem_eof_return(bio,0);
			}
		}
	}
	BIO_push(out,bio);
	bio=NULL;
	if (0)
		{
err:
		if (out != NULL)
			BIO_free_all(out);
		if (btmp != NULL)
			BIO_free_all(btmp);
		out=NULL;
		}
	return(out);
	}
Пример #2
0
int
enc_main(int argc, char **argv)
{
	static const char magic[] = "Salted__";
	char mbuf[sizeof magic - 1];
	char *strbuf = NULL, *pass = NULL;
	unsigned char *buff = NULL;
	int bsize = BSIZE;
	int ret = 1, inl;
	unsigned char key[EVP_MAX_KEY_LENGTH], iv[EVP_MAX_IV_LENGTH];
	unsigned char salt[PKCS5_SALT_LEN];
#ifdef ZLIB
	BIO *bzl = NULL;
#endif
	EVP_CIPHER_CTX *ctx = NULL;
	const EVP_MD *dgst = NULL;
	BIO *in = NULL, *out = NULL, *b64 = NULL, *benc = NULL;
	BIO *rbio = NULL, *wbio = NULL;
#define PROG_NAME_SIZE  39
	char pname[PROG_NAME_SIZE + 1];
	int i;

	if (single_execution) {
		if (pledge("stdio rpath wpath cpath tty", NULL) == -1) {
			perror("pledge");
			exit(1);
		}
	}

	memset(&enc_config, 0, sizeof(enc_config));
	enc_config.enc = 1;

	/* first check the program name */
	program_name(argv[0], pname, sizeof(pname));

	if (strcmp(pname, "base64") == 0)
		enc_config.base64 = 1;

#ifdef ZLIB
	if (strcmp(pname, "zlib") == 0)
		enc_config.do_zlib = 1;
#endif

	enc_config.cipher = EVP_get_cipherbyname(pname);

#ifdef ZLIB
	if (!enc_config.do_zlib && !enc_config.base64 &&
	    enc_config.cipher == NULL && strcmp(pname, "enc") != 0)
#else
	if (!enc_config.base64 && enc_config.cipher == NULL &&
	    strcmp(pname, "enc") != 0)
#endif
	{
		BIO_printf(bio_err, "%s is an unknown cipher\n", pname);
		goto end;
	}

	if (options_parse(argc, argv, enc_options, NULL, NULL) != 0) {
		enc_usage();
		goto end;
	}

	if (enc_config.keyfile != NULL) {
		static char buf[128];
		FILE *infile;

		infile = fopen(enc_config.keyfile, "r");
		if (infile == NULL) {
			BIO_printf(bio_err, "unable to read key from '%s'\n",
			    enc_config.keyfile);
			goto end;
		}
		buf[0] = '\0';
		if (!fgets(buf, sizeof buf, infile)) {
			BIO_printf(bio_err, "unable to read key from '%s'\n",
			    enc_config.keyfile);
			fclose(infile);
			goto end;
		}
		fclose(infile);
		i = strlen(buf);
		if ((i > 0) && ((buf[i - 1] == '\n') || (buf[i - 1] == '\r')))
			buf[--i] = '\0';
		if ((i > 0) && ((buf[i - 1] == '\n') || (buf[i - 1] == '\r')))
			buf[--i] = '\0';
		if (i < 1) {
			BIO_printf(bio_err, "zero length password\n");
			goto end;
		}
		enc_config.keystr = buf;
	}

	if (enc_config.md != NULL &&
	    (dgst = EVP_get_digestbyname(enc_config.md)) == NULL) {
		BIO_printf(bio_err,
		    "%s is an unsupported message digest type\n",
		    enc_config.md);
		goto end;
	}
	if (dgst == NULL) {
		dgst = EVP_md5();	/* XXX */
	}

	if (enc_config.bufsize != NULL) {
		char *p = enc_config.bufsize;
		unsigned long n;

		/* XXX - provide an OPTION_ARG_DISKUNIT. */
		for (n = 0; *p != '\0'; p++) {
			i = *p;
			if ((i <= '9') && (i >= '0'))
				n = n * 10 + i - '0';
			else if (i == 'k') {
				n *= 1024;
				p++;
				break;
			}
		}
		if (*p != '\0') {
			BIO_printf(bio_err, "invalid 'bufsize' specified.\n");
			goto end;
		}
		/* It must be large enough for a base64 encoded line. */
		if (enc_config.base64 && n < 80)
			n = 80;

		bsize = (int)n;
		if (enc_config.verbose)
			BIO_printf(bio_err, "bufsize=%d\n", bsize);
	}
	strbuf = malloc(SIZE);
	buff = malloc(EVP_ENCODE_LENGTH(bsize));
	if ((buff == NULL) || (strbuf == NULL)) {
		BIO_printf(bio_err, "malloc failure %ld\n", (long) EVP_ENCODE_LENGTH(bsize));
		goto end;
	}
	in = BIO_new(BIO_s_file());
	out = BIO_new(BIO_s_file());
	if ((in == NULL) || (out == NULL)) {
		ERR_print_errors(bio_err);
		goto end;
	}
	if (enc_config.debug) {
		BIO_set_callback(in, BIO_debug_callback);
		BIO_set_callback(out, BIO_debug_callback);
		BIO_set_callback_arg(in, (char *) bio_err);
		BIO_set_callback_arg(out, (char *) bio_err);
	}
	if (enc_config.inf == NULL) {
		if (enc_config.bufsize != NULL)
			setvbuf(stdin, (char *) NULL, _IONBF, 0);
		BIO_set_fp(in, stdin, BIO_NOCLOSE);
	} else {
		if (BIO_read_filename(in, enc_config.inf) <= 0) {
			perror(enc_config.inf);
			goto end;
		}
	}

	if (!enc_config.keystr && enc_config.passarg) {
		if (!app_passwd(bio_err, enc_config.passarg, NULL,
		    &pass, NULL)) {
			BIO_printf(bio_err, "Error getting password\n");
			goto end;
		}
		enc_config.keystr = pass;
	}
	if (enc_config.keystr == NULL && enc_config.cipher != NULL &&
	    enc_config.hkey == NULL) {
		for (;;) {
			char buf[200];
			int retval;

			retval = snprintf(buf, sizeof buf,
			    "enter %s %s password:"******"encryption" : "decryption");
			if ((size_t)retval >= sizeof buf) {
				BIO_printf(bio_err,
				    "Password prompt too long\n");
				goto end;
			}
			strbuf[0] = '\0';
			i = EVP_read_pw_string((char *)strbuf, SIZE, buf,
			    enc_config.enc);
			if (i == 0) {
				if (strbuf[0] == '\0') {
					ret = 1;
					goto end;
				}
				enc_config.keystr = strbuf;
				break;
			}
			if (i < 0) {
				BIO_printf(bio_err, "bad password read\n");
				goto end;
			}
		}
	}
	if (enc_config.outf == NULL) {
		BIO_set_fp(out, stdout, BIO_NOCLOSE);
		if (enc_config.bufsize != NULL)
			setvbuf(stdout, (char *)NULL, _IONBF, 0);
	} else {
		if (BIO_write_filename(out, enc_config.outf) <= 0) {
			perror(enc_config.outf);
			goto end;
		}
	}

	rbio = in;
	wbio = out;

#ifdef ZLIB
	if (do_zlib) {
		if ((bzl = BIO_new(BIO_f_zlib())) == NULL)
			goto end;
		if (enc)
			wbio = BIO_push(bzl, wbio);
		else
			rbio = BIO_push(bzl, rbio);
	}
#endif

	if (enc_config.base64) {
		if ((b64 = BIO_new(BIO_f_base64())) == NULL)
			goto end;
		if (enc_config.debug) {
			BIO_set_callback(b64, BIO_debug_callback);
			BIO_set_callback_arg(b64, (char *) bio_err);
		}
		if (enc_config.olb64)
			BIO_set_flags(b64, BIO_FLAGS_BASE64_NO_NL);
		if (enc_config.enc)
			wbio = BIO_push(b64, wbio);
		else
			rbio = BIO_push(b64, rbio);
	}
	if (enc_config.cipher != NULL) {
		/*
		 * Note that keystr is NULL if a key was passed on the command
		 * line, so we get no salt in that case. Is this a bug?
		 */
		if (enc_config.keystr != NULL) {
			/*
			 * Salt handling: if encrypting generate a salt and
			 * write to output BIO. If decrypting read salt from
			 * input BIO.
			 */
			unsigned char *sptr;
			if (enc_config.nosalt)
				sptr = NULL;
			else {
				if (enc_config.enc) {
					if (enc_config.hsalt) {
						if (!set_hex(enc_config.hsalt, salt, sizeof salt)) {
							BIO_printf(bio_err,
							    "invalid hex salt value\n");
							goto end;
						}
					} else
						arc4random_buf(salt,
						    sizeof(salt));
					/*
					 * If -P option then don't bother
					 * writing
					 */
					if ((enc_config.printkey != 2)
					    && (BIO_write(wbio, magic,
						    sizeof magic - 1) != sizeof magic - 1
						|| BIO_write(wbio,
						    (char *) salt,
						    sizeof salt) != sizeof salt)) {
						BIO_printf(bio_err, "error writing output file\n");
						goto end;
					}
				} else if (BIO_read(rbio, mbuf, sizeof mbuf) != sizeof mbuf
					    || BIO_read(rbio,
						(unsigned char *) salt,
					sizeof salt) != sizeof salt) {
					BIO_printf(bio_err, "error reading input file\n");
					goto end;
				} else if (memcmp(mbuf, magic, sizeof magic - 1)) {
					BIO_printf(bio_err, "bad magic number\n");
					goto end;
				}
				sptr = salt;
			}

			EVP_BytesToKey(enc_config.cipher, dgst, sptr,
			    (unsigned char *)enc_config.keystr,
			    strlen(enc_config.keystr), 1, key, iv);
			/*
			 * zero the complete buffer or the string passed from
			 * the command line bug picked up by Larry J. Hughes
			 * Jr. <*****@*****.**>
			 */
			if (enc_config.keystr == strbuf)
				explicit_bzero(enc_config.keystr, SIZE);
			else
				explicit_bzero(enc_config.keystr,
				    strlen(enc_config.keystr));
		}
		if (enc_config.hiv != NULL &&
		    !set_hex(enc_config.hiv, iv, sizeof iv)) {
			BIO_printf(bio_err, "invalid hex iv value\n");
			goto end;
		}
		if (enc_config.hiv == NULL && enc_config.keystr == NULL &&
		    EVP_CIPHER_iv_length(enc_config.cipher) != 0) {
			/*
			 * No IV was explicitly set and no IV was generated
			 * during EVP_BytesToKey. Hence the IV is undefined,
			 * making correct decryption impossible.
			 */
			BIO_printf(bio_err, "iv undefined\n");
			goto end;
		}
		if (enc_config.hkey != NULL &&
		    !set_hex(enc_config.hkey, key, sizeof key)) {
			BIO_printf(bio_err, "invalid hex key value\n");
			goto end;
		}
		if ((benc = BIO_new(BIO_f_cipher())) == NULL)
			goto end;

		/*
		 * Since we may be changing parameters work on the encryption
		 * context rather than calling BIO_set_cipher().
		 */

		BIO_get_cipher_ctx(benc, &ctx);

		if (!EVP_CipherInit_ex(ctx, enc_config.cipher, NULL, NULL,
		    NULL, enc_config.enc)) {
			BIO_printf(bio_err, "Error setting cipher %s\n",
			    EVP_CIPHER_name(enc_config.cipher));
			ERR_print_errors(bio_err);
			goto end;
		}
		if (enc_config.nopad)
			EVP_CIPHER_CTX_set_padding(ctx, 0);

		if (!EVP_CipherInit_ex(ctx, NULL, NULL, key, iv,
		    enc_config.enc)) {
			BIO_printf(bio_err, "Error setting cipher %s\n",
			    EVP_CIPHER_name(enc_config.cipher));
			ERR_print_errors(bio_err);
			goto end;
		}
		if (enc_config.debug) {
			BIO_set_callback(benc, BIO_debug_callback);
			BIO_set_callback_arg(benc, (char *) bio_err);
		}
		if (enc_config.printkey) {
			if (!enc_config.nosalt) {
				printf("salt=");
				for (i = 0; i < (int) sizeof(salt); i++)
					printf("%02X", salt[i]);
				printf("\n");
			}
			if (enc_config.cipher->key_len > 0) {
				printf("key=");
				for (i = 0; i < enc_config.cipher->key_len; i++)
					printf("%02X", key[i]);
				printf("\n");
			}
			if (enc_config.cipher->iv_len > 0) {
				printf("iv =");
				for (i = 0; i < enc_config.cipher->iv_len; i++)
					printf("%02X", iv[i]);
				printf("\n");
			}
			if (enc_config.printkey == 2) {
				ret = 0;
				goto end;
			}
		}
	}
	/* Only encrypt/decrypt as we write the file */
	if (benc != NULL)
		wbio = BIO_push(benc, wbio);

	for (;;) {
		inl = BIO_read(rbio, (char *) buff, bsize);
		if (inl <= 0)
			break;
		if (BIO_write(wbio, (char *) buff, inl) != inl) {
			BIO_printf(bio_err, "error writing output file\n");
			goto end;
		}
	}
	if (!BIO_flush(wbio)) {
		BIO_printf(bio_err, "bad decrypt\n");
		goto end;
	}
	ret = 0;
	if (enc_config.verbose) {
		BIO_printf(bio_err, "bytes read   :%8ld\n", BIO_number_read(in));
		BIO_printf(bio_err, "bytes written:%8ld\n", BIO_number_written(out));
	}
end:
	ERR_print_errors(bio_err);
	free(strbuf);
	free(buff);
	BIO_free(in);
	if (out != NULL)
		BIO_free_all(out);
	BIO_free(benc);
	BIO_free(b64);
#ifdef ZLIB
	BIO_free(bzl);
#endif
	free(pass);

	return (ret);
}
Пример #3
0
int
cipher_ctx_reset(EVP_CIPHER_CTX *ctx, const uint8_t *iv_buf)
{
    return EVP_CipherInit_ex(ctx, NULL, NULL, NULL, iv_buf, -1);
}
Пример #4
0
OM_uint32 _gssapi_unwrap_arcfour(OM_uint32 *minor_status,
				 const gsskrb5_ctx context_handle,
				 krb5_context context,
				 const gss_buffer_t input_message_buffer,
				 gss_buffer_t output_message_buffer,
				 int *conf_state,
				 gss_qop_t *qop_state,
				 krb5_keyblock *key)
{
    u_char Klocaldata[16];
    krb5_keyblock Klocal;
    krb5_error_code ret;
    uint32_t seq_number;
    size_t datalen;
    OM_uint32 omret;
    u_char k6_data[16], SND_SEQ[8], Confounder[8];
    u_char cksum_data[8];
    u_char *p, *p0;
    int cmp;
    int conf_flag;
    size_t padlen = 0, len;

    if (conf_state)
	*conf_state = 0;
    if (qop_state)
	*qop_state = 0;

    p0 = input_message_buffer->value;

    if (IS_DCE_STYLE(context_handle)) {
	len = GSS_ARCFOUR_WRAP_TOKEN_SIZE +
	    GSS_ARCFOUR_WRAP_TOKEN_DCE_DER_HEADER_SIZE;
	if (input_message_buffer->length < len)
	    return GSS_S_BAD_MECH;
    } else {
	len = input_message_buffer->length;
    }

    omret = _gssapi_verify_mech_header(&p0,
				       len,
				       GSS_KRB5_MECHANISM);
    if (omret)
	return omret;

    /* length of mech header */
    len = (p0 - (u_char *)input_message_buffer->value) +
	GSS_ARCFOUR_WRAP_TOKEN_SIZE;

    if (len > input_message_buffer->length)
	return GSS_S_BAD_MECH;

    /* length of data */
    datalen = input_message_buffer->length - len;

    p = p0;

    if (memcmp(p, "\x02\x01", 2) != 0)
	return GSS_S_BAD_SIG;
    p += 2;
    if (memcmp(p, "\x11\x00", 2) != 0) /* SGN_ALG = HMAC MD5 ARCFOUR */
	return GSS_S_BAD_SIG;
    p += 2;

    if (memcmp (p, "\x10\x00", 2) == 0)
	conf_flag = 1;
    else if (memcmp (p, "\xff\xff", 2) == 0)
	conf_flag = 0;
    else
	return GSS_S_BAD_SIG;

    p += 2;
    if (memcmp (p, "\xff\xff", 2) != 0)
	return GSS_S_BAD_MIC;
    p = NULL;

    ret = arcfour_mic_key(context, key,
			  p0 + 16, 8, /* SGN_CKSUM */
			  k6_data, sizeof(k6_data));
    if (ret) {
	*minor_status = ret;
	return GSS_S_FAILURE;
    }

    {
	EVP_CIPHER_CTX rc4_key;

	EVP_CIPHER_CTX_init(&rc4_key);
	EVP_CipherInit_ex(&rc4_key, EVP_rc4(), NULL, k6_data, NULL, 1);
	EVP_Cipher(&rc4_key, SND_SEQ, p0 + 8, 8);
	EVP_CIPHER_CTX_cleanup(&rc4_key);
	memset(k6_data, 0, sizeof(k6_data));
    }

    _gss_mg_decode_be_uint32(SND_SEQ, &seq_number);

    if (context_handle->more_flags & LOCAL)
	cmp = memcmp(&SND_SEQ[4], "\xff\xff\xff\xff", 4);
    else
	cmp = memcmp(&SND_SEQ[4], "\x00\x00\x00\x00", 4);

    if (cmp != 0) {
	*minor_status = 0;
	return GSS_S_BAD_MIC;
    }

    {
	int i;

	Klocal.keytype = key->keytype;
	Klocal.keyvalue.data = Klocaldata;
	Klocal.keyvalue.length = sizeof(Klocaldata);

	for (i = 0; i < 16; i++)
	    Klocaldata[i] = ((u_char *)key->keyvalue.data)[i] ^ 0xF0;
    }
    ret = arcfour_mic_key(context, &Klocal,
			  SND_SEQ, 4,
			  k6_data, sizeof(k6_data));
    memset(Klocaldata, 0, sizeof(Klocaldata));
    if (ret) {
	*minor_status = ret;
	return GSS_S_FAILURE;
    }

    output_message_buffer->value = malloc(datalen);
    if (output_message_buffer->value == NULL) {
	*minor_status = ENOMEM;
	return GSS_S_FAILURE;
    }
    output_message_buffer->length = datalen;

    if(conf_flag) {
	EVP_CIPHER_CTX rc4_key;

	EVP_CIPHER_CTX_init(&rc4_key);
	EVP_CipherInit_ex(&rc4_key, EVP_rc4(), NULL, k6_data, NULL, 1);
	EVP_Cipher(&rc4_key, Confounder, p0 + 24, 8);
	EVP_Cipher(&rc4_key, output_message_buffer->value, p0 + GSS_ARCFOUR_WRAP_TOKEN_SIZE, datalen);
	EVP_CIPHER_CTX_cleanup(&rc4_key);
    } else {
	memcpy(Confounder, p0 + 24, 8); /* Confounder */
	memcpy(output_message_buffer->value,
	       p0 + GSS_ARCFOUR_WRAP_TOKEN_SIZE,
	       datalen);
    }
    memset(k6_data, 0, sizeof(k6_data));

    if (!IS_DCE_STYLE(context_handle)) {
	ret = _gssapi_verify_pad(output_message_buffer, datalen, &padlen);
	if (ret) {
	    _gsskrb5_release_buffer(minor_status, output_message_buffer);
	    *minor_status = 0;
	    return ret;
	}
	output_message_buffer->length -= padlen;
    }

    ret = arcfour_mic_cksum(context,
			    key, KRB5_KU_USAGE_SEAL,
			    cksum_data, sizeof(cksum_data),
			    p0, 8,
			    Confounder, sizeof(Confounder),
			    output_message_buffer->value,
			    output_message_buffer->length + padlen);
    if (ret) {
	_gsskrb5_release_buffer(minor_status, output_message_buffer);
	*minor_status = ret;
	return GSS_S_FAILURE;
    }

    cmp = ct_memcmp(cksum_data, p0 + 16, 8); /* SGN_CKSUM */
    if (cmp) {
	_gsskrb5_release_buffer(minor_status, output_message_buffer);
	*minor_status = 0;
	return GSS_S_BAD_MIC;
    }

    HEIMDAL_MUTEX_lock(&context_handle->ctx_id_mutex);
    omret = _gssapi_msg_order_check(context_handle->gk5c.order, seq_number);
    HEIMDAL_MUTEX_unlock(&context_handle->ctx_id_mutex);
    if (omret)
	return omret;

    if (conf_state)
	*conf_state = conf_flag;

    *minor_status = 0;
    return GSS_S_COMPLETE;
}
Пример #5
0
/* int */
BIO *
PKCS7_dataDecode(PKCS7 *p7, EVP_PKEY *pkey, BIO *in_bio, X509 *pcert)
{
	int i, j;
	BIO *out = NULL, *btmp = NULL, *etmp = NULL, *bio = NULL;
	X509_ALGOR *xa;
	ASN1_OCTET_STRING *data_body = NULL;
	const EVP_MD *evp_md;
	const EVP_CIPHER *evp_cipher = NULL;
	EVP_CIPHER_CTX *evp_ctx = NULL;
	X509_ALGOR *enc_alg = NULL;
	STACK_OF(X509_ALGOR) *md_sk = NULL;
	STACK_OF(PKCS7_RECIP_INFO) *rsk = NULL;
	PKCS7_RECIP_INFO *ri = NULL;
	unsigned char *ek = NULL, *tkey = NULL;
	int eklen = 0, tkeylen = 0;

	i = OBJ_obj2nid(p7->type);
	p7->state = PKCS7_S_HEADER;

	switch (i) {
	case NID_pkcs7_signed:
		data_body = PKCS7_get_octet_string(p7->d.sign->contents);
		md_sk = p7->d.sign->md_algs;
		break;
	case NID_pkcs7_signedAndEnveloped:
		rsk = p7->d.signed_and_enveloped->recipientinfo;
		md_sk = p7->d.signed_and_enveloped->md_algs;
		data_body = p7->d.signed_and_enveloped->enc_data->enc_data;
		enc_alg = p7->d.signed_and_enveloped->enc_data->algorithm;
		evp_cipher = EVP_get_cipherbyobj(enc_alg->algorithm);
		if (evp_cipher == NULL) {
			PKCS7err(PKCS7_F_PKCS7_DATADECODE,
			    PKCS7_R_UNSUPPORTED_CIPHER_TYPE);
			goto err;
		}
		break;
	case NID_pkcs7_enveloped:
		rsk = p7->d.enveloped->recipientinfo;
		enc_alg = p7->d.enveloped->enc_data->algorithm;
		data_body = p7->d.enveloped->enc_data->enc_data;
		evp_cipher = EVP_get_cipherbyobj(enc_alg->algorithm);
		if (evp_cipher == NULL) {
			PKCS7err(PKCS7_F_PKCS7_DATADECODE,
			    PKCS7_R_UNSUPPORTED_CIPHER_TYPE);
			goto err;
		}
		break;
	default:
		PKCS7err(PKCS7_F_PKCS7_DATADECODE,
		    PKCS7_R_UNSUPPORTED_CONTENT_TYPE);
		goto err;
	}

	/* We will be checking the signature */
	if (md_sk != NULL) {
		for (i = 0; i < sk_X509_ALGOR_num(md_sk); i++) {
			xa = sk_X509_ALGOR_value(md_sk, i);
			if ((btmp = BIO_new(BIO_f_md())) == NULL) {
				PKCS7err(PKCS7_F_PKCS7_DATADECODE,
				    ERR_R_BIO_LIB);
				goto err;
			}

			j = OBJ_obj2nid(xa->algorithm);
			evp_md = EVP_get_digestbynid(j);
			if (evp_md == NULL) {
				PKCS7err(PKCS7_F_PKCS7_DATADECODE,
				    PKCS7_R_UNKNOWN_DIGEST_TYPE);
				goto err;
			}

			BIO_set_md(btmp, evp_md);
			if (out == NULL)
				out = btmp;
			else
				BIO_push(out, btmp);
			btmp = NULL;
		}
	}

	if (evp_cipher != NULL) {
#if 0
		unsigned char key[EVP_MAX_KEY_LENGTH];
		unsigned char iv[EVP_MAX_IV_LENGTH];
		unsigned char *p;
		int keylen, ivlen;
		int max;
		X509_OBJECT ret;
#endif

		if ((etmp = BIO_new(BIO_f_cipher())) == NULL) {
			PKCS7err(PKCS7_F_PKCS7_DATADECODE, ERR_R_BIO_LIB);
			goto err;
		}

		/* It was encrypted, we need to decrypt the secret key
		 * with the private key */

		/* Find the recipientInfo which matches the passed certificate
		 * (if any)
		 */
		if (pcert) {
			for (i = 0; i < sk_PKCS7_RECIP_INFO_num(rsk); i++) {
				ri = sk_PKCS7_RECIP_INFO_value(rsk, i);
				if (!pkcs7_cmp_ri(ri, pcert))
					break;
				ri = NULL;
			}
			if (ri == NULL) {
				PKCS7err(PKCS7_F_PKCS7_DATADECODE,
				    PKCS7_R_NO_RECIPIENT_MATCHES_CERTIFICATE);
				goto err;
			}
		}

		/* If we haven't got a certificate try each ri in turn */
		if (pcert == NULL) {
			/* Always attempt to decrypt all rinfo even
			 * after sucess as a defence against MMA timing
			 * attacks.
			 */
			for (i = 0; i < sk_PKCS7_RECIP_INFO_num(rsk); i++) {
				ri = sk_PKCS7_RECIP_INFO_value(rsk, i);

				if (pkcs7_decrypt_rinfo(&ek, &eklen,
				    ri, pkey) < 0)
					goto err;
				ERR_clear_error();
			}
		} else {
			/* Only exit on fatal errors, not decrypt failure */
			if (pkcs7_decrypt_rinfo(&ek, &eklen, ri, pkey) < 0)
				goto err;
			ERR_clear_error();
		}

		evp_ctx = NULL;
		BIO_get_cipher_ctx(etmp, &evp_ctx);
		if (EVP_CipherInit_ex(evp_ctx, evp_cipher, NULL, NULL,
		    NULL, 0) <= 0)
			goto err;
		if (EVP_CIPHER_asn1_to_param(evp_ctx, enc_alg->parameter) < 0)
			goto err;
		/* Generate random key as MMA defence */
		tkeylen = EVP_CIPHER_CTX_key_length(evp_ctx);
		tkey = malloc(tkeylen);
		if (!tkey)
			goto err;
		if (EVP_CIPHER_CTX_rand_key(evp_ctx, tkey) <= 0)
			goto err;
		if (ek == NULL) {
			ek = tkey;
			eklen = tkeylen;
			tkey = NULL;
		}

		if (eklen != EVP_CIPHER_CTX_key_length(evp_ctx)) {
			/* Some S/MIME clients don't use the same key
			 * and effective key length. The key length is
			 * determined by the size of the decrypted RSA key.
			 */
			if (!EVP_CIPHER_CTX_set_key_length(evp_ctx, eklen)) {
				/* Use random key as MMA defence */
				OPENSSL_cleanse(ek, eklen);
				free(ek);
				ek = tkey;
				eklen = tkeylen;
				tkey = NULL;
			}
		}
		/* Clear errors so we don't leak information useful in MMA */
		ERR_clear_error();
		if (EVP_CipherInit_ex(evp_ctx, NULL, NULL, ek, NULL, 0) <= 0)
			goto err;

		if (ek) {
			OPENSSL_cleanse(ek, eklen);
			free(ek);
			ek = NULL;
		}
		if (tkey) {
			OPENSSL_cleanse(tkey, tkeylen);
			free(tkey);
			tkey = NULL;
		}

		if (out == NULL)
			out = etmp;
		else
			BIO_push(out, etmp);
		etmp = NULL;
	}

#if 1
	if (PKCS7_is_detached(p7) || (in_bio != NULL)) {
		bio = in_bio;
	} else {
#if 0
		bio = BIO_new(BIO_s_mem());
		/* We need to set this so that when we have read all
		 * the data, the encrypt BIO, if present, will read
		 * EOF and encode the last few bytes */
		BIO_set_mem_eof_return(bio, 0);

		if (data_body != NULL && data_body->length > 0)
			BIO_write(bio, (char *)data_body->data, data_body->length);
#else
		if (data_body != NULL && data_body->length > 0)
			bio = BIO_new_mem_buf(data_body->data, data_body->length);
		else {
			bio = BIO_new(BIO_s_mem());
			BIO_set_mem_eof_return(bio, 0);
		}
		if (bio == NULL)
			goto err;
#endif
	}
	BIO_push(out, bio);
	bio = NULL;
#endif
	if (0) {
err:
		if (ek) {
			OPENSSL_cleanse(ek, eklen);
			free(ek);
		}
		if (tkey) {
			OPENSSL_cleanse(tkey, tkeylen);
			free(tkey);
		}
		if (out != NULL)
			BIO_free_all(out);
		if (btmp != NULL)
			BIO_free_all(btmp);
		if (etmp != NULL)
			BIO_free_all(etmp);
		if (bio != NULL)
			BIO_free_all(bio);
		out = NULL;
	}
	return (out);
}
Пример #6
0
int ssl3_change_cipher_state(SSL *s, int which)
	{
	unsigned char *p,*mac_secret;
	unsigned char exp_key[EVP_MAX_KEY_LENGTH];
	unsigned char exp_iv[EVP_MAX_IV_LENGTH];
	unsigned char *ms,*key,*iv,*er1,*er2;
	EVP_CIPHER_CTX *dd;
	const EVP_CIPHER *c;
#ifndef OPENSSL_NO_COMP
	COMP_METHOD *comp;
#endif
	const EVP_MD *m;
	EVP_MD_CTX md;
	int is_exp,n,i,j,k,cl;
	int reuse_dd = 0;

	is_exp=SSL_C_IS_EXPORT(s->s3->tmp.new_cipher);
	c=s->s3->tmp.new_sym_enc;
	m=s->s3->tmp.new_hash;
#ifndef OPENSSL_NO_COMP
	if (s->s3->tmp.new_compression == NULL)
		comp=NULL;
	else
		comp=s->s3->tmp.new_compression->method;
#endif

	if (which & SSL3_CC_READ)
		{
		if (s->enc_read_ctx != NULL)
			reuse_dd = 1;
		else if ((s->enc_read_ctx=OPENSSL_malloc(sizeof(EVP_CIPHER_CTX))) == NULL)
			goto err;
		else
			/* make sure it's intialized in case we exit later with an error */
			EVP_CIPHER_CTX_init(s->enc_read_ctx);
		dd= s->enc_read_ctx;
		s->read_hash=m;
#ifndef OPENSSL_NO_COMP
		/* COMPRESS */
		if (s->expand != NULL)
			{
			COMP_CTX_free(s->expand);
			s->expand=NULL;
			}
		if (comp != NULL)
			{
			s->expand=COMP_CTX_new(comp);
			if (s->expand == NULL)
				{
				SSLerr(SSL_F_SSL3_CHANGE_CIPHER_STATE,SSL_R_COMPRESSION_LIBRARY_ERROR);
				goto err2;
				}
			if (s->s3->rrec.comp == NULL)
				s->s3->rrec.comp=(unsigned char *)
					OPENSSL_malloc(SSL3_RT_MAX_PLAIN_LENGTH);
			if (s->s3->rrec.comp == NULL)
				goto err;
			}
#endif
		memset(&(s->s3->read_sequence[0]),0,8);
		mac_secret= &(s->s3->read_mac_secret[0]);
		}
	else
		{
		if (s->enc_write_ctx != NULL)
			reuse_dd = 1;
		else if ((s->enc_write_ctx=OPENSSL_malloc(sizeof(EVP_CIPHER_CTX))) == NULL)
			goto err;
		else
			/* make sure it's intialized in case we exit later with an error */
			EVP_CIPHER_CTX_init(s->enc_write_ctx);
		dd= s->enc_write_ctx;
		s->write_hash=m;
#ifndef OPENSSL_NO_COMP
		/* COMPRESS */
		if (s->compress != NULL)
			{
			COMP_CTX_free(s->compress);
			s->compress=NULL;
			}
		if (comp != NULL)
			{
			s->compress=COMP_CTX_new(comp);
			if (s->compress == NULL)
				{
				SSLerr(SSL_F_SSL3_CHANGE_CIPHER_STATE,SSL_R_COMPRESSION_LIBRARY_ERROR);
				goto err2;
				}
			}
#endif
		memset(&(s->s3->write_sequence[0]),0,8);
		mac_secret= &(s->s3->write_mac_secret[0]);
		}

	if (reuse_dd)
		EVP_CIPHER_CTX_cleanup(dd);

	p=s->s3->tmp.key_block;
	i=EVP_MD_size(m);
	cl=EVP_CIPHER_key_length(c);
	j=is_exp ? (cl < SSL_C_EXPORT_KEYLENGTH(s->s3->tmp.new_cipher) ?
		 cl : SSL_C_EXPORT_KEYLENGTH(s->s3->tmp.new_cipher)) : cl;
	/* Was j=(is_exp)?5:EVP_CIPHER_key_length(c); */
	k=EVP_CIPHER_iv_length(c);
	if (	(which == SSL3_CHANGE_CIPHER_CLIENT_WRITE) ||
		(which == SSL3_CHANGE_CIPHER_SERVER_READ))
		{
		ms=  &(p[ 0]); n=i+i;
		key= &(p[ n]); n+=j+j;
		iv=  &(p[ n]); n+=k+k;
		er1= &(s->s3->client_random[0]);
		er2= &(s->s3->server_random[0]);
		}
	else
		{
		n=i;
		ms=  &(p[ n]); n+=i+j;
		key= &(p[ n]); n+=j+k;
		iv=  &(p[ n]); n+=k;
		er1= &(s->s3->server_random[0]);
		er2= &(s->s3->client_random[0]);
		}

	if (n > s->s3->tmp.key_block_length)
		{
		SSLerr(SSL_F_SSL3_CHANGE_CIPHER_STATE,ERR_R_INTERNAL_ERROR);
		goto err2;
		}

	EVP_MD_CTX_init(&md);
	memcpy(mac_secret,ms,i);
	if (is_exp)
		{
		/* In here I set both the read and write key/iv to the
		 * same value since only the correct one will be used :-).
		 */
		EVP_DigestInit_ex(&md,EVP_md5(), NULL);
		EVP_DigestUpdate(&md,key,j);
		EVP_DigestUpdate(&md,er1,SSL3_RANDOM_SIZE);
		EVP_DigestUpdate(&md,er2,SSL3_RANDOM_SIZE);
		EVP_DigestFinal_ex(&md,&(exp_key[0]),NULL);
		key= &(exp_key[0]);

		if (k > 0)
			{
			EVP_DigestInit_ex(&md,EVP_md5(), NULL);
			EVP_DigestUpdate(&md,er1,SSL3_RANDOM_SIZE);
			EVP_DigestUpdate(&md,er2,SSL3_RANDOM_SIZE);
			EVP_DigestFinal_ex(&md,&(exp_iv[0]),NULL);
			iv= &(exp_iv[0]);
			}
		}

	s->session->key_arg_length=0;

	EVP_CipherInit_ex(dd,c,NULL,key,iv,(which & SSL3_CC_WRITE));

	OPENSSL_cleanse(&(exp_key[0]),sizeof(exp_key));
	OPENSSL_cleanse(&(exp_iv[0]),sizeof(exp_iv));
	EVP_MD_CTX_cleanup(&md);
	return(1);
err:
	SSLerr(SSL_F_SSL3_CHANGE_CIPHER_STATE,ERR_R_MALLOC_FAILURE);
err2:
	return(0);
	}
Пример #7
0
OM_uint32
_gssapi_verify_mic_arcfour(OM_uint32 * minor_status,
			   const gsskrb5_ctx context_handle,
			   krb5_context context,
			   const gss_buffer_t message_buffer,
			   const gss_buffer_t token_buffer,
			   gss_qop_t * qop_state,
			   krb5_keyblock *key,
			   const char *type)
{
    krb5_error_code ret;
    uint32_t seq_number;
    OM_uint32 omret;
    u_char SND_SEQ[8], cksum_data[8], *p;
    char k6_data[16];
    int cmp;

    if (qop_state)
	*qop_state = 0;

    p = token_buffer->value;
    omret = _gsskrb5_verify_header (&p,
				       token_buffer->length,
				       type,
				       GSS_KRB5_MECHANISM);
    if (omret)
	return omret;

    if (memcmp(p, "\x11\x00", 2) != 0) /* SGN_ALG = HMAC MD5 ARCFOUR */
	return GSS_S_BAD_SIG;
    p += 2;
    if (memcmp (p, "\xff\xff\xff\xff", 4) != 0)
	return GSS_S_BAD_MIC;
    p += 4;

    ret = arcfour_mic_cksum(context,
			    key, KRB5_KU_USAGE_SIGN,
			    cksum_data, sizeof(cksum_data),
			    p - 8, 8,
			    message_buffer->value, message_buffer->length,
			    NULL, 0);
    if (ret) {
	*minor_status = ret;
	return GSS_S_FAILURE;
    }

    ret = arcfour_mic_key(context, key,
			  cksum_data, sizeof(cksum_data),
			  k6_data, sizeof(k6_data));
    if (ret) {
	*minor_status = ret;
	return GSS_S_FAILURE;
    }

    cmp = ct_memcmp(cksum_data, p + 8, 8);
    if (cmp) {
	*minor_status = 0;
	return GSS_S_BAD_MIC;
    }

    {
	EVP_CIPHER_CTX rc4_key;

	EVP_CIPHER_CTX_init(&rc4_key);
	EVP_CipherInit_ex(&rc4_key, EVP_rc4(), NULL, (void *)k6_data, NULL, 0);
	EVP_Cipher(&rc4_key, SND_SEQ, p, 8);
	EVP_CIPHER_CTX_cleanup(&rc4_key);

	memset(k6_data, 0, sizeof(k6_data));
    }

    _gss_mg_decode_be_uint32(SND_SEQ, &seq_number);

    if (context_handle->more_flags & LOCAL)
	cmp = memcmp(&SND_SEQ[4], "\xff\xff\xff\xff", 4);
    else
	cmp = memcmp(&SND_SEQ[4], "\x00\x00\x00\x00", 4);

    memset(SND_SEQ, 0, sizeof(SND_SEQ));
    if (cmp != 0) {
	*minor_status = 0;
	return GSS_S_BAD_MIC;
    }

    HEIMDAL_MUTEX_lock(&context_handle->ctx_id_mutex);
    omret = _gssapi_msg_order_check(context_handle->gk5c.order, seq_number);
    HEIMDAL_MUTEX_unlock(&context_handle->ctx_id_mutex);
    if (omret)
	return omret;

    *minor_status = 0;
    return GSS_S_COMPLETE;
}
Пример #8
0
BIO *cms_EncryptedContent_init_bio(CMS_EncryptedContentInfo *ec)
{
    BIO *b;
    EVP_CIPHER_CTX *ctx;
    const EVP_CIPHER *ciph;
    X509_ALGOR *calg = ec->contentEncryptionAlgorithm;
    unsigned char iv[EVP_MAX_IV_LENGTH], *piv = NULL;
    unsigned char *tkey = NULL;
    size_t tkeylen = 0;

    int ok = 0;

    int enc, keep_key = 0;

    enc = ec->cipher ? 1 : 0;

    b = BIO_new(BIO_f_cipher());
    if (b == NULL) {
        CMSerr(CMS_F_CMS_ENCRYPTEDCONTENT_INIT_BIO, ERR_R_MALLOC_FAILURE);
        return NULL;
    }

    BIO_get_cipher_ctx(b, &ctx);

    if (enc) {
        ciph = ec->cipher;
        /*
         * If not keeping key set cipher to NULL so subsequent calls decrypt.
         */
        if (ec->key)
            ec->cipher = NULL;
    } else {
        ciph = EVP_get_cipherbyobj(calg->algorithm);

        if (!ciph) {
            CMSerr(CMS_F_CMS_ENCRYPTEDCONTENT_INIT_BIO, CMS_R_UNKNOWN_CIPHER);
            goto err;
        }
    }

    if (EVP_CipherInit_ex(ctx, ciph, NULL, NULL, NULL, enc) <= 0) {
        CMSerr(CMS_F_CMS_ENCRYPTEDCONTENT_INIT_BIO,
               CMS_R_CIPHER_INITIALISATION_ERROR);
        goto err;
    }

    if (enc) {
        int ivlen;
        calg->algorithm = OBJ_nid2obj(EVP_CIPHER_CTX_type(ctx));
        /* Generate a random IV if we need one */
        ivlen = EVP_CIPHER_CTX_iv_length(ctx);
        if (ivlen > 0) {
            if (RAND_bytes(iv, ivlen) <= 0)
                goto err;
            piv = iv;
        }
    } else if (EVP_CIPHER_asn1_to_param(ctx, calg->parameter) <= 0) {
        CMSerr(CMS_F_CMS_ENCRYPTEDCONTENT_INIT_BIO,
               CMS_R_CIPHER_PARAMETER_INITIALISATION_ERROR);
        goto err;
    }
    tkeylen = EVP_CIPHER_CTX_key_length(ctx);
    /* Generate random session key */
    if (!enc || !ec->key) {
        tkey = OPENSSL_malloc(tkeylen);
        if (tkey == NULL) {
            CMSerr(CMS_F_CMS_ENCRYPTEDCONTENT_INIT_BIO, ERR_R_MALLOC_FAILURE);
            goto err;
        }
        if (EVP_CIPHER_CTX_rand_key(ctx, tkey) <= 0)
            goto err;
    }

    if (!ec->key) {
        ec->key = tkey;
        ec->keylen = tkeylen;
        tkey = NULL;
        if (enc)
            keep_key = 1;
        else
            ERR_clear_error();

    }

    if (ec->keylen != tkeylen) {
        /* If necessary set key length */
        if (EVP_CIPHER_CTX_set_key_length(ctx, ec->keylen) <= 0) {
            /*
             * Only reveal failure if debugging so we don't leak information
             * which may be useful in MMA.
             */
            if (enc || ec->debug) {
                CMSerr(CMS_F_CMS_ENCRYPTEDCONTENT_INIT_BIO,
                       CMS_R_INVALID_KEY_LENGTH);
                goto err;
            } else {
                /* Use random key */
                OPENSSL_clear_free(ec->key, ec->keylen);
                ec->key = tkey;
                ec->keylen = tkeylen;
                tkey = NULL;
                ERR_clear_error();
            }
        }
    }

    if (EVP_CipherInit_ex(ctx, NULL, NULL, ec->key, piv, enc) <= 0) {
        CMSerr(CMS_F_CMS_ENCRYPTEDCONTENT_INIT_BIO,
               CMS_R_CIPHER_INITIALISATION_ERROR);
        goto err;
    }
    if (enc) {
        calg->parameter = ASN1_TYPE_new();
        if (calg->parameter == NULL) {
            CMSerr(CMS_F_CMS_ENCRYPTEDCONTENT_INIT_BIO, ERR_R_MALLOC_FAILURE);
            goto err;
        }
        if (EVP_CIPHER_param_to_asn1(ctx, calg->parameter) <= 0) {
            CMSerr(CMS_F_CMS_ENCRYPTEDCONTENT_INIT_BIO,
                   CMS_R_CIPHER_PARAMETER_INITIALISATION_ERROR);
            goto err;
        }
        /* If parameter type not set omit parameter */
        if (calg->parameter->type == V_ASN1_UNDEF) {
            ASN1_TYPE_free(calg->parameter);
            calg->parameter = NULL;
        }
    }
    ok = 1;

 err:
    if (!keep_key || !ok) {
        OPENSSL_clear_free(ec->key, ec->keylen);
        ec->key = NULL;
    }
    OPENSSL_clear_free(tkey, tkeylen);
    if (ok)
        return b;
    BIO_free(b);
    return NULL;
}
Пример #9
0
void cipher_context_init(cipher_ctx_t *ctx, int method, int enc)
{
    if (method <= TABLE || method >= CIPHER_NUM) {
        LOGE("cipher_context_init(): Illegal method");
        return;
    }

    if (method >= SALSA20) {
        enc_iv_len = supported_ciphers_iv_size[method];
        return;
    }

    const char *ciphername = supported_ciphers[method];
#if defined(USE_CRYPTO_APPLECC)
    cipher_cc_t *cc = &ctx->cc;
    cc->cryptor = NULL;
    cc->cipher  = supported_ciphers_applecc[method];
    if (cc->cipher == kCCAlgorithmInvalid) {
        cc->valid = kCCContextInvalid;
    } else {
        cc->valid = kCCContextValid;
        if (cc->cipher == kCCAlgorithmRC4) {
            cc->mode    = kCCModeRC4;
            cc->padding = ccNoPadding;
        } else {
            cc->mode    = kCCModeCFB;
            cc->padding = ccPKCS7Padding;
        }
        return;
    }
#endif

    cipher_evp_t *evp         = &ctx->evp;
    const cipher_kt_t *cipher = get_cipher_type(method);
#if defined(USE_CRYPTO_OPENSSL)
    if (cipher == NULL) {
        LOGE("Cipher %s not found in OpenSSL library", ciphername);
        FATAL("Cannot initialize cipher");
    }
    EVP_CIPHER_CTX_init(evp);
    if (!EVP_CipherInit_ex(evp, cipher, NULL, NULL, NULL, enc)) {
        LOGE("Cannot initialize cipher %s", ciphername);
        exit(EXIT_FAILURE);
    }
    if (!EVP_CIPHER_CTX_set_key_length(evp, enc_key_len)) {
        EVP_CIPHER_CTX_cleanup(evp);
        LOGE("Invalid key length: %d", enc_key_len);
        exit(EXIT_FAILURE);
    }
    if (method > RC4_MD5) {
        EVP_CIPHER_CTX_set_padding(evp, 1);
    }
#elif defined(USE_CRYPTO_POLARSSL)
    if (cipher == NULL) {
        LOGE("Cipher %s not found in PolarSSL library", ciphername);
        FATAL("Cannot initialize PolarSSL cipher");
    }
    if (cipher_init_ctx(evp, cipher) != 0) {
        FATAL("Cannot initialize PolarSSL cipher context");
    }
#elif defined(USE_CRYPTO_MBEDTLS)
    // XXX: mbedtls_cipher_setup future change
    // NOTE:  Currently also clears structure. In future versions you will be required to call
    //        mbedtls_cipher_init() on the structure first.
    //        void mbedtls_cipher_init( mbedtls_cipher_context_t *ctx );
    if (cipher == NULL) {
        LOGE("Cipher %s not found in mbed TLS library", ciphername);
        FATAL("Cannot initialize mbed TLS cipher");
    }
    mbedtls_cipher_init(evp);
    if (mbedtls_cipher_setup(evp, cipher) != 0) {
        FATAL("Cannot initialize mbed TLS cipher context");
    }
#endif
}
Пример #10
0
long _IKED::packet_ike_encrypt( IDB_PH1 * sa, PACKET_IKE & packet, BDATA * iv )
{
	log.txt( LLOG_INFO,
		">= : cookies %08x%08x:%08x%08x\n",
		htonl( *( long * ) &sa->cookies.i[ 0 ] ),
		htonl( *( long * ) &sa->cookies.i[ 4 ] ),
		htonl( *( long * ) &sa->cookies.r[ 0 ] ),
		htonl( *( long * ) &sa->cookies.r[ 4 ] ) );

	log.txt( LLOG_INFO,
		">= : message %08x\n",
		htonl( packet.get_msgid() ) );

	//
	// check if encrypt is required
	//

	unsigned char *	data = packet.buff();
	size_t		    size = packet.size();

	if( !( data[ ISAKMP_FLAGS_OFFSET ] & ISAKMP_FLAG_ENCRYPT ) )
		return LIBIKE_OK;

	log.bin(
		LLOG_DEBUG,
		LLOG_DECODE,
		iv->buff(),
		iv->size(),
		">= : encrypt iv" );

	log.bin(
		LLOG_DEBUG,
		LLOG_DECODE,
		packet.buff(),
		packet.size(),
		"== : encrypt packet" );

	//
	// determine pad length
	//

	size_t plen = size - sizeof( IKE_HEADER );
	size_t blen = EVP_CIPHER_block_size( sa->evp_cipher );
	size_t padd = 0;

	if( plen % blen )
		padd += blen - ( plen % blen );

	packet.add_null( padd );

	data = packet.buff();
	size = packet.size();

	//
	// set new packet length in header
	//

	IKE_HEADER * header = ( IKE_HEADER * ) packet.buff();
	header->length = htonl( ( uint32_t ) size );

	//
	// init cipher key and iv and
	// encrypt all but header
	//

	EVP_CIPHER_CTX ctx_cipher;
	EVP_CIPHER_CTX_init( &ctx_cipher );

	EVP_CipherInit_ex(
		&ctx_cipher,
		sa->evp_cipher,
		NULL,
		NULL,
		NULL,
		1 );

	EVP_CIPHER_CTX_set_key_length(
		&ctx_cipher,
		( int ) sa->key.size() );

	EVP_CipherInit_ex(
		&ctx_cipher,
		NULL,
		NULL,
		sa->key.buff(),
		iv->buff(),
		1 );

	EVP_Cipher(
		&ctx_cipher,
		data + sizeof( IKE_HEADER ),
		data + sizeof( IKE_HEADER ),
		( int ) size - sizeof( IKE_HEADER ) );

	EVP_CIPHER_CTX_cleanup( &ctx_cipher );

	//
	// store cipher iv data
	//

	memcpy(
		iv->buff(),
		data + size - iv->size(),
		iv->size() );

	log.bin(
		LLOG_DEBUG,
		LLOG_DECODE,
		iv->buff(),
		iv->size(),
		"== : stored iv" );

	return LIBIKE_OK;
}
Пример #11
0
krb5_error_code
_krb5_evp_encrypt_cts(krb5_context context,
		      struct _krb5_key_data *key,
		      void *data,
		      size_t len,
		      krb5_boolean encryptp,
		      int usage,
		      void *ivec)
{
    size_t i, blocksize;
    struct _krb5_evp_schedule *ctx = key->schedule->data;
    char tmp[EVP_MAX_BLOCK_LENGTH], ivec2[EVP_MAX_BLOCK_LENGTH];
    EVP_CIPHER_CTX *c;
    unsigned char *p;

    c = encryptp ? &ctx->ectx : &ctx->dctx;

    blocksize = EVP_CIPHER_CTX_block_size(c);

    if (len < blocksize) {
	krb5_set_error_message(context, EINVAL,
			       "message block too short");
	return EINVAL;
    } else if (len == blocksize) {
	EVP_CipherInit_ex(c, NULL, NULL, NULL, zero_ivec, -1);
	EVP_Cipher(c, data, data, len);
	return 0;
    }

    if (ivec)
	EVP_CipherInit_ex(c, NULL, NULL, NULL, ivec, -1);
    else
	EVP_CipherInit_ex(c, NULL, NULL, NULL, zero_ivec, -1);

    if (encryptp) {

	p = data;
	i = ((len - 1) / blocksize) * blocksize;
	EVP_Cipher(c, p, p, i);
	p += i - blocksize;
	len -= i;
	memcpy(ivec2, p, blocksize);

	for (i = 0; i < len; i++)
	    tmp[i] = p[i + blocksize] ^ ivec2[i];
	for (; i < blocksize; i++)
	    tmp[i] = 0 ^ ivec2[i];

	EVP_CipherInit_ex(c, NULL, NULL, NULL, zero_ivec, -1);
	EVP_Cipher(c, p, tmp, blocksize);

	memcpy(p + blocksize, ivec2, len);
	if (ivec)
	    memcpy(ivec, p, blocksize);
    } else {
	char tmp2[EVP_MAX_BLOCK_LENGTH], tmp3[EVP_MAX_BLOCK_LENGTH];

	p = data;
	if (len > blocksize * 2) {
	    /* remove last two blocks and round up, decrypt this with cbc, then do cts dance */
	    i = ((((len - blocksize * 2) + blocksize - 1) / blocksize) * blocksize);
	    memcpy(ivec2, p + i - blocksize, blocksize);
	    EVP_Cipher(c, p, p, i);
	    p += i;
	    len -= i + blocksize;
	} else {
	    if (ivec)
		memcpy(ivec2, ivec, blocksize);
	    else
		memcpy(ivec2, zero_ivec, blocksize);
	    len -= blocksize;
	}

	memcpy(tmp, p, blocksize);
	EVP_CipherInit_ex(c, NULL, NULL, NULL, zero_ivec, -1);
	EVP_Cipher(c, tmp2, p, blocksize);

	memcpy(tmp3, p + blocksize, len);
	memcpy(tmp3 + len, tmp2 + len, blocksize - len); /* xor 0 */

	for (i = 0; i < len; i++)
	    p[i + blocksize] = tmp2[i] ^ tmp3[i];

	EVP_CipherInit_ex(c, NULL, NULL, NULL, zero_ivec, -1);
	EVP_Cipher(c, p, tmp3, blocksize);

	for (i = 0; i < blocksize; i++)
	    p[i] ^= ivec2[i];
	if (ivec)
	    memcpy(ivec, tmp, blocksize);
    }
    return 0;
}
Пример #12
0
long _IKED::packet_ike_decrypt( IDB_PH1 * sa, PACKET_IKE & packet, BDATA * iv )
{
	log.txt( LLOG_INFO,
		"=< : cookies %08x%08x:%08x%08x\n",
		htonl( *( long * ) &sa->cookies.i[ 0 ] ),
		htonl( *( long * ) &sa->cookies.i[ 4 ] ),
		htonl( *( long * ) &sa->cookies.r[ 0 ] ),
		htonl( *( long * ) &sa->cookies.r[ 4 ] ) );

	log.txt( LLOG_INFO,
		"=< : message %08x\n",
		htonl( packet.get_msgid() ) );

	//
	// check if decrypt is required
	//

	unsigned char *	data = packet.buff();
	size_t		    size = packet.size();

	if( !( data[ ISAKMP_FLAGS_OFFSET ] & ISAKMP_FLAG_ENCRYPT ) )
		return LIBIKE_OK;

	log.bin(
		LLOG_DEBUG,
		LLOG_DECODE,
		iv->buff(),
		iv->size(),
		"=< : decrypt iv" );

	//
	// temporarily save enough
	// of the packet to store
	// as iv data post decrypt
	//

	unsigned char iv_data[ HMAC_MAX_MD_CBLOCK ];

	memcpy(
		iv_data,
		data + size - iv->size(),
		iv->size() );

	//
	// init cipher key and iv
	//

	EVP_CIPHER_CTX ctx_cipher;
	EVP_CIPHER_CTX_init( &ctx_cipher );

	EVP_CipherInit_ex(
		&ctx_cipher,
		sa->evp_cipher,
		NULL,
		NULL,
		NULL,
		0 );

	EVP_CIPHER_CTX_set_key_length(
		&ctx_cipher,
		( int ) sa->key.size() );

	EVP_CipherInit_ex(
		&ctx_cipher,
		NULL,
		NULL,
		sa->key.buff(),
		iv->buff(),
		0 );

	//
	// decrypt all but header
	//

	EVP_Cipher(
		&ctx_cipher,
		data + sizeof( IKE_HEADER ),
		data + sizeof( IKE_HEADER ),
		( int ) size - sizeof( IKE_HEADER ) );

	EVP_CIPHER_CTX_cleanup( &ctx_cipher );

	log.bin(
		LLOG_DEBUG,
		LLOG_DECODE,
		data,
		size,
		"== : decrypt packet" );

	//
	// validate the packet integrity
	//

	IKE_HEADER * header = ( IKE_HEADER * ) packet.buff();

	size = sizeof( IKE_HEADER );

	if( packet.size() < size )
	{
		log.txt( LLOG_ERROR,
			"!! : validate packet failed ( truncated header )\n" );

		return LIBIKE_FAILED;
	}

	while( true )
	{
		IKE_PAYLOAD * payload = ( IKE_PAYLOAD * )( packet.buff() + size );

		if( packet.size() < ( size + sizeof( IKE_PAYLOAD ) ) )
		{
			log.txt( LLOG_ERROR,
				"!! : validate packet failed ( truncated payload )\n" );

			return LIBIKE_FAILED;
		}

		if( payload->reserved )
		{
			log.txt( LLOG_ERROR,
				"!! : validate packet failed ( reserved value is non-null )\n" );

			return LIBIKE_FAILED;
		}

		size += ntohs( payload->length );

		if( packet.size() < size )
		{
			log.txt( LLOG_ERROR,
				"!! : validate packet failed ( payload length is invalid )\n" );

			return LIBIKE_FAILED;
		}

		if( payload->next == ISAKMP_PAYLOAD_NONE )
			break;
	}

	//
	// validate packet padding. if the encrypted
	// packet size is equal to the ike message
	// length, we can skip this step. although the
	// RFC states there should at least be one pad
	// byte that describes the padding length, if
	// we are strict we will break compatibility
	// with many implementations including cisco
	//

	if( size < packet.size() )
	{
		//
		// trim packet padding
		//

		size_t diff = packet.size() - size;

		packet.size( size );

		log.txt( LLOG_DEBUG,
			"<= : trimmed packet padding ( %i bytes )\n",
			 diff );

		header = ( IKE_HEADER * ) packet.buff();
		header->length = htonl( ( uint32_t ) size );
	}

	//
	// store cipher iv data
	//

	memcpy(
		iv->buff(),
		iv_data,
		iv->size() );

	log.bin(
		LLOG_DEBUG,
		LLOG_DECODE,
		iv->buff(),
		iv->size(),
		"<= : stored iv" );
	
	return LIBIKE_OK;
}
Пример #13
0
static int
try_decrypt(hx509_context context,
	    struct hx509_collector *collector,
	    const AlgorithmIdentifier *alg,
	    const EVP_CIPHER *c,
	    const void *ivdata,
	    const void *password,
	    size_t passwordlen,
	    const void *cipher,
	    size_t len)
{
    heim_octet_string clear;
    size_t keylen;
    void *key;
    int ret;

    keylen = EVP_CIPHER_key_length(c);

    key = malloc(keylen);
    if (key == NULL) {
	hx509_clear_error_string(context);
	return ENOMEM;
    }

    ret = EVP_BytesToKey(c, EVP_md5(), ivdata,
			 password, passwordlen,
			 1, key, NULL);
    if (ret <= 0) {
	hx509_set_error_string(context, 0, HX509_CRYPTO_INTERNAL_ERROR,
			       "Failed to do string2key for private key");
	return HX509_CRYPTO_INTERNAL_ERROR;
    }

    clear.data = malloc(len);
    if (clear.data == NULL) {
	hx509_set_error_string(context, 0, ENOMEM,
			       "Out of memory to decrypt for private key");
	ret = ENOMEM;
	goto out;
    }
    clear.length = len;

    {
	EVP_CIPHER_CTX ctx;
	EVP_CIPHER_CTX_init(&ctx);
	EVP_CipherInit_ex(&ctx, c, NULL, key, ivdata, 0);
	EVP_Cipher(&ctx, clear.data, cipher, len);
	EVP_CIPHER_CTX_cleanup(&ctx);
    }	

    ret = _hx509_collector_private_key_add(context,
					   collector,
					   alg,
					   NULL,
					   &clear,
					   NULL);

    memset(clear.data, 0, clear.length);
    free(clear.data);
out:
    memset(key, 0, keylen);
    free(key);
    return ret;
}
Пример #14
0
/* int */
BIO *PKCS7_dataDecode(PKCS7 *p7, EVP_PKEY *pkey, BIO *in_bio, X509 *pcert)
	{
	int i,j;
	BIO *out=NULL,*btmp=NULL,*etmp=NULL,*bio=NULL;
	unsigned char *tmp=NULL;
	X509_ALGOR *xa;
	ASN1_OCTET_STRING *data_body=NULL;
	const EVP_MD *evp_md;
	const EVP_CIPHER *evp_cipher=NULL;
	EVP_CIPHER_CTX *evp_ctx=NULL;
	X509_ALGOR *enc_alg=NULL;
	STACK_OF(X509_ALGOR) *md_sk=NULL;
	STACK_OF(PKCS7_RECIP_INFO) *rsk=NULL;
	X509_ALGOR *xalg=NULL;
	PKCS7_RECIP_INFO *ri=NULL;

	i=OBJ_obj2nid(p7->type);
	p7->state=PKCS7_S_HEADER;

	switch (i)
		{
	case NID_pkcs7_signed:
		data_body=p7->d.sign->contents->d.data;
		md_sk=p7->d.sign->md_algs;
		break;
	case NID_pkcs7_signedAndEnveloped:
		rsk=p7->d.signed_and_enveloped->recipientinfo;
		md_sk=p7->d.signed_and_enveloped->md_algs;
		data_body=p7->d.signed_and_enveloped->enc_data->enc_data;
		enc_alg=p7->d.signed_and_enveloped->enc_data->algorithm;
		evp_cipher=EVP_get_cipherbyname(OBJ_nid2sn(OBJ_obj2nid(enc_alg->algorithm)));
		if (evp_cipher == NULL)
			{
			PKCS7err(PKCS7_F_PKCS7_DATADECODE,PKCS7_R_UNSUPPORTED_CIPHER_TYPE);
			goto err;
			}
		xalg=p7->d.signed_and_enveloped->enc_data->algorithm;
		break;
	case NID_pkcs7_enveloped:
		rsk=p7->d.enveloped->recipientinfo;
		enc_alg=p7->d.enveloped->enc_data->algorithm;
		data_body=p7->d.enveloped->enc_data->enc_data;
		evp_cipher=EVP_get_cipherbyname(OBJ_nid2sn(OBJ_obj2nid(enc_alg->algorithm)));
		if (evp_cipher == NULL)
			{
			PKCS7err(PKCS7_F_PKCS7_DATADECODE,PKCS7_R_UNSUPPORTED_CIPHER_TYPE);
			goto err;
			}
		xalg=p7->d.enveloped->enc_data->algorithm;
		break;
	default:
		PKCS7err(PKCS7_F_PKCS7_DATADECODE,PKCS7_R_UNSUPPORTED_CONTENT_TYPE);
	        goto err;
		}

	/* We will be checking the signature */
	if (md_sk != NULL)
		{
		for (i=0; i<sk_X509_ALGOR_num(md_sk); i++)
			{
			xa=sk_X509_ALGOR_value(md_sk,i);
			if ((btmp=BIO_new(BIO_f_md())) == NULL)
				{
				PKCS7err(PKCS7_F_PKCS7_DATADECODE,ERR_R_BIO_LIB);
				goto err;
				}

			j=OBJ_obj2nid(xa->algorithm);
			evp_md=EVP_get_digestbyname(OBJ_nid2sn(j));
			if (evp_md == NULL)
				{
				PKCS7err(PKCS7_F_PKCS7_DATADECODE,PKCS7_R_UNKNOWN_DIGEST_TYPE);
				goto err;
				}

			BIO_set_md(btmp,evp_md);
			if (out == NULL)
				out=btmp;
			else
				BIO_push(out,btmp);
			btmp=NULL;
			}
		}

	if (evp_cipher != NULL)
		{
#if 0
		unsigned char key[EVP_MAX_KEY_LENGTH];
		unsigned char iv[EVP_MAX_IV_LENGTH];
		unsigned char *p;
		int keylen,ivlen;
		int max;
		X509_OBJECT ret;
#endif
		int jj;

		if ((etmp=BIO_new(BIO_f_cipher())) == NULL)
			{
			PKCS7err(PKCS7_F_PKCS7_DATADECODE,ERR_R_BIO_LIB);
			goto err;
			}

		/* It was encrypted, we need to decrypt the secret key
		 * with the private key */

		/* Find the recipientInfo which matches the passed certificate
		 * (if any)
		 */

		for (i=0; i<sk_PKCS7_RECIP_INFO_num(rsk); i++) {
			ri=sk_PKCS7_RECIP_INFO_value(rsk,i);
			if(!X509_NAME_cmp(ri->issuer_and_serial->issuer,
					pcert->cert_info->issuer) &&
			     !M_ASN1_INTEGER_cmp(pcert->cert_info->serialNumber,
					ri->issuer_and_serial->serial)) break;
			ri=NULL;
		}
		if (ri == NULL) {
			PKCS7err(PKCS7_F_PKCS7_DATADECODE,
				 PKCS7_R_NO_RECIPIENT_MATCHES_CERTIFICATE);
			goto err;
		}

		jj=EVP_PKEY_size(pkey);
		tmp=(unsigned char *)OPENSSL_malloc(jj+10);
		if (tmp == NULL)
			{
			PKCS7err(PKCS7_F_PKCS7_DATADECODE,ERR_R_MALLOC_FAILURE);
			goto err;
			}

		jj=EVP_PKEY_decrypt(tmp, M_ASN1_STRING_data(ri->enc_key),
			M_ASN1_STRING_length(ri->enc_key), pkey);
		if (jj <= 0)
			{
			PKCS7err(PKCS7_F_PKCS7_DATADECODE,ERR_R_EVP_LIB);
			goto err;
			}

		evp_ctx=NULL;
		BIO_get_cipher_ctx(etmp,&evp_ctx);
		EVP_CipherInit_ex(evp_ctx,evp_cipher,NULL,NULL,NULL,0);
		if (EVP_CIPHER_asn1_to_param(evp_ctx,enc_alg->parameter) < 0)
			goto err;

		if (jj != EVP_CIPHER_CTX_key_length(evp_ctx)) {
			/* Some S/MIME clients don't use the same key
			 * and effective key length. The key length is
			 * determined by the size of the decrypted RSA key.
			 */
			if(!EVP_CIPHER_CTX_set_key_length(evp_ctx, jj))
				{
				PKCS7err(PKCS7_F_PKCS7_DATADECODE,
					PKCS7_R_DECRYPTED_KEY_IS_WRONG_LENGTH);
				goto err;
				}
		} 
		EVP_CipherInit_ex(evp_ctx,NULL,NULL,tmp,NULL,0);

		OPENSSL_cleanse(tmp,jj);

		if (out == NULL)
			out=etmp;
		else
			BIO_push(out,etmp);
		etmp=NULL;
		}

#if 1
	if (PKCS7_is_detached(p7) || (in_bio != NULL))
		{
		bio=in_bio;
		}
	else 
		{
#if 0
		bio=BIO_new(BIO_s_mem());
		/* We need to set this so that when we have read all
		 * the data, the encrypt BIO, if present, will read
		 * EOF and encode the last few bytes */
		BIO_set_mem_eof_return(bio,0);

		if (data_body->length > 0)
			BIO_write(bio,(char *)data_body->data,data_body->length);
#else
		if (data_body->length > 0)
		      bio = BIO_new_mem_buf(data_body->data,data_body->length);
		else {
			bio=BIO_new(BIO_s_mem());
			BIO_set_mem_eof_return(bio,0);
		}
#endif
		}
	BIO_push(out,bio);
	bio=NULL;
#endif
	if (0)
		{
err:
		if (out != NULL) BIO_free_all(out);
		if (btmp != NULL) BIO_free_all(btmp);
		if (etmp != NULL) BIO_free_all(etmp);
		if (bio != NULL) BIO_free_all(bio);
		out=NULL;
		}
	if (tmp != NULL)
		OPENSSL_free(tmp);
	return(out);
	}
Пример #15
0
BIO *
PKCS7_dataInit(PKCS7 *p7, BIO *bio)
{
	int i;
	BIO *out = NULL, *btmp = NULL;
	X509_ALGOR *xa = NULL;
	const EVP_CIPHER *evp_cipher = NULL;
	STACK_OF(X509_ALGOR) *md_sk = NULL;
	STACK_OF(PKCS7_RECIP_INFO) *rsk = NULL;
	X509_ALGOR *xalg = NULL;
	PKCS7_RECIP_INFO *ri = NULL;
	ASN1_OCTET_STRING *os = NULL;

	if (p7 == NULL) {
		PKCS7err(PKCS7_F_PKCS7_DATAINIT, PKCS7_R_INVALID_NULL_POINTER);
		return NULL;
	}

	/*
	 * The content field in the PKCS7 ContentInfo is optional,
	 * but that really only applies to inner content (precisely,
	 * detached signatures).
	 *
	 * When reading content, missing outer content is therefore
	 * treated as an error.
	 *
	 * When creating content, PKCS7_content_new() must be called
	 * before calling this method, so a NULL p7->d is always
	 * an error.
	 */
	if (p7->d.ptr == NULL) {
		PKCS7err(PKCS7_F_PKCS7_DATAINIT, PKCS7_R_NO_CONTENT);
		return NULL;
	}

	i = OBJ_obj2nid(p7->type);
	p7->state = PKCS7_S_HEADER;

	switch (i) {
	case NID_pkcs7_signed:
		md_sk = p7->d.sign->md_algs;
		os = PKCS7_get_octet_string(p7->d.sign->contents);
		break;
	case NID_pkcs7_signedAndEnveloped:
		rsk = p7->d.signed_and_enveloped->recipientinfo;
		md_sk = p7->d.signed_and_enveloped->md_algs;
		xalg = p7->d.signed_and_enveloped->enc_data->algorithm;
		evp_cipher = p7->d.signed_and_enveloped->enc_data->cipher;
		if (evp_cipher == NULL) {
			PKCS7err(PKCS7_F_PKCS7_DATAINIT,
			    PKCS7_R_CIPHER_NOT_INITIALIZED);
			goto err;
		}
		break;
	case NID_pkcs7_enveloped:
		rsk = p7->d.enveloped->recipientinfo;
		xalg = p7->d.enveloped->enc_data->algorithm;
		evp_cipher = p7->d.enveloped->enc_data->cipher;
		if (evp_cipher == NULL) {
			PKCS7err(PKCS7_F_PKCS7_DATAINIT,
			    PKCS7_R_CIPHER_NOT_INITIALIZED);
			goto err;
		}
		break;
	case NID_pkcs7_digest:
		xa = p7->d.digest->md;
		os = PKCS7_get_octet_string(p7->d.digest->contents);
		break;
	case NID_pkcs7_data:
		break;
	default:
		PKCS7err(PKCS7_F_PKCS7_DATAINIT,
		    PKCS7_R_UNSUPPORTED_CONTENT_TYPE);
		goto err;
	}

	for (i = 0; i < sk_X509_ALGOR_num(md_sk); i++)
		if (!PKCS7_bio_add_digest(&out, sk_X509_ALGOR_value(md_sk, i)))
			goto err;

	if (xa && !PKCS7_bio_add_digest(&out, xa))
		goto err;

	if (evp_cipher != NULL) {
		unsigned char key[EVP_MAX_KEY_LENGTH];
		unsigned char iv[EVP_MAX_IV_LENGTH];
		int keylen, ivlen;
		EVP_CIPHER_CTX *ctx;

		if ((btmp = BIO_new(BIO_f_cipher())) == NULL) {
			PKCS7err(PKCS7_F_PKCS7_DATAINIT, ERR_R_BIO_LIB);
			goto err;
		}
		BIO_get_cipher_ctx(btmp, &ctx);
		keylen = EVP_CIPHER_key_length(evp_cipher);
		ivlen = EVP_CIPHER_iv_length(evp_cipher);
		xalg->algorithm = OBJ_nid2obj(EVP_CIPHER_type(evp_cipher));
		if (ivlen > 0)
			arc4random_buf(iv, ivlen);
		if (EVP_CipherInit_ex(ctx, evp_cipher, NULL, NULL,
		    NULL, 1) <= 0)
			goto err;
		if (EVP_CIPHER_CTX_rand_key(ctx, key) <= 0)
			goto err;
		if (EVP_CipherInit_ex(ctx, NULL, NULL, key, iv, 1) <= 0)
			goto err;

		if (ivlen > 0) {
			if (xalg->parameter == NULL) {
				xalg->parameter = ASN1_TYPE_new();
				if (xalg->parameter == NULL)
					goto err;
			}
			if (EVP_CIPHER_param_to_asn1(ctx, xalg->parameter) < 0)
				goto err;
		}

		/* Lets do the pub key stuff :-) */
		for (i = 0; i < sk_PKCS7_RECIP_INFO_num(rsk); i++) {
			ri = sk_PKCS7_RECIP_INFO_value(rsk, i);
			if (pkcs7_encode_rinfo(ri, key, keylen) <= 0)
				goto err;
		}
		explicit_bzero(key, keylen);

		if (out == NULL)
			out = btmp;
		else
			BIO_push(out, btmp);
		btmp = NULL;
	}

	if (bio == NULL) {
		if (PKCS7_is_detached(p7))
			bio = BIO_new(BIO_s_null());
		else if (os && os->length > 0)
			bio = BIO_new_mem_buf(os->data, os->length);
		if (bio == NULL) {
			bio = BIO_new(BIO_s_mem());
			if (bio == NULL)
				goto err;
			BIO_set_mem_eof_return(bio, 0);
		}
	}
	if (out)
		BIO_push(out, bio);
	else
		out = bio;
	bio = NULL;
	if (0) {
err:
		if (out != NULL)
			BIO_free_all(out);
		if (btmp != NULL)
			BIO_free_all(btmp);
		out = NULL;
	}
	return (out);
}
Пример #16
0
void cipher_context_set_iv(cipher_ctx_t *ctx, uint8_t *iv, size_t iv_len,
                           int enc)
{
    const unsigned char *true_key;

    if (iv == NULL) {
        LOGE("cipher_context_set_iv(): IV is null");
        return;
    }

    if (!enc) {
        memcpy(ctx->iv, iv, iv_len);
    }

    if (enc_method >= SALSA20) {
        return;
    }

    if (enc_method == RC4_MD5) {
        unsigned char key_iv[32];
        memcpy(key_iv, enc_key, 16);
        memcpy(key_iv + 16, iv, 16);
        true_key = enc_md5(key_iv, 32, NULL);
        iv_len   = 0;
    } else {
        true_key = enc_key;
    }

#ifdef USE_CRYPTO_APPLECC
    cipher_cc_t *cc = &ctx->cc;
    if (cc->valid == kCCContextValid) {
        memcpy(cc->iv, iv, iv_len);
        memcpy(cc->key, true_key, enc_key_len);
        cc->iv_len  = iv_len;
        cc->key_len = enc_key_len;
        cc->encrypt = enc ? kCCEncrypt : kCCDecrypt;
        if (cc->cryptor != NULL) {
            CCCryptorRelease(cc->cryptor);
            cc->cryptor = NULL;
        }

        CCCryptorStatus ret;
        ret = CCCryptorCreateWithMode(
            cc->encrypt,
            cc->mode,
            cc->cipher,
            cc->padding,
            cc->iv, cc->key, cc->key_len,
            NULL, 0, 0, 0,
            &cc->cryptor);
        if (ret != kCCSuccess) {
            if (cc->cryptor != NULL) {
                CCCryptorRelease(cc->cryptor);
                cc->cryptor = NULL;
            }
            FATAL("Cannot set CommonCrypto key and IV");
        }
        return;
    }
#endif

    cipher_evp_t *evp = &ctx->evp;
    if (evp == NULL) {
        LOGE("cipher_context_set_iv(): Cipher context is null");
        return;
    }
#if defined(USE_CRYPTO_OPENSSL)
    if (!EVP_CipherInit_ex(evp, NULL, NULL, true_key, iv, enc)) {
        EVP_CIPHER_CTX_cleanup(evp);
        FATAL("Cannot set key and IV");
    }
#elif defined(USE_CRYPTO_POLARSSL)
    // XXX: PolarSSL 1.3.11: cipher_free_ctx deprecated, Use cipher_free() instead.
    if (cipher_setkey(evp, true_key, enc_key_len * 8, enc) != 0) {
        cipher_free_ctx(evp);
        FATAL("Cannot set PolarSSL cipher key");
    }
#if POLARSSL_VERSION_NUMBER >= 0x01030000
    if (cipher_set_iv(evp, iv, iv_len) != 0) {
        cipher_free_ctx(evp);
        FATAL("Cannot set PolarSSL cipher IV");
    }
    if (cipher_reset(evp) != 0) {
        cipher_free_ctx(evp);
        FATAL("Cannot finalize PolarSSL cipher context");
    }
#else
    if (cipher_reset(evp, iv) != 0) {
        cipher_free_ctx(evp);
        FATAL("Cannot set PolarSSL cipher IV");
    }
#endif
#elif defined(USE_CRYPTO_MBEDTLS)
    if (mbedtls_cipher_setkey(evp, true_key, enc_key_len * 8, enc) != 0) {
        mbedtls_cipher_free(evp);
        FATAL("Cannot set mbed TLS cipher key");
    }

    if (mbedtls_cipher_set_iv(evp, iv, iv_len) != 0) {
        mbedtls_cipher_free(evp);
        FATAL("Cannot set mbed TLS cipher IV");
    }
    if (mbedtls_cipher_reset(evp) != 0) {
        mbedtls_cipher_free(evp);
        FATAL("Cannot finalize mbed TLS cipher context");
    }
#endif

#ifdef DEBUG
    dump("IV", (char *)iv, iv_len);
#endif
}
Пример #17
0
int tls1_change_cipher_state(SSL *s, int which)
	{
	static const unsigned char empty[]="";
	unsigned char *p,*key_block,*mac_secret;
	unsigned char *exp_label;
	unsigned char tmp1[EVP_MAX_KEY_LENGTH];
	unsigned char tmp2[EVP_MAX_KEY_LENGTH];
	unsigned char iv1[EVP_MAX_IV_LENGTH*2];
	unsigned char iv2[EVP_MAX_IV_LENGTH*2];
	unsigned char *ms,*key,*iv,*er1,*er2;
	int client_write;
	EVP_CIPHER_CTX *dd;
	const EVP_CIPHER *c;
#ifndef OPENSSL_NO_COMP
	const SSL_COMP *comp;
#endif
	const EVP_MD *m;
	int mac_type;
	int *mac_secret_size;
	EVP_MD_CTX *mac_ctx;
	EVP_PKEY *mac_key;
	int is_export,n,i,j,k,exp_label_len,cl;
	int reuse_dd = 0;

	is_export=SSL_C_IS_EXPORT(s->s3->tmp.new_cipher);
	c=s->s3->tmp.new_sym_enc;
	m=s->s3->tmp.new_hash;
	mac_type = s->s3->tmp.new_mac_pkey_type;
#ifndef OPENSSL_NO_COMP
	comp=s->s3->tmp.new_compression;
#endif
	key_block=s->s3->tmp.key_block;

#ifdef KSSL_DEBUG
	printf("tls1_change_cipher_state(which= %d) w/\n", which);
	printf("\talg= %ld/%ld, comp= %p\n",
	       s->s3->tmp.new_cipher->algorithm_mkey,
	       s->s3->tmp.new_cipher->algorithm_auth,
	       comp);
	printf("\tevp_cipher == %p ==? &d_cbc_ede_cipher3\n", c);
	printf("\tevp_cipher: nid, blksz= %d, %d, keylen=%d, ivlen=%d\n",
                c->nid,c->block_size,c->key_len,c->iv_len);
	printf("\tkey_block: len= %d, data= ", s->s3->tmp.key_block_length);
	{
        int i;
        for (i=0; i<s->s3->tmp.key_block_length; i++)
		printf("%02x", key_block[i]);  printf("\n");
        }
#endif	/* KSSL_DEBUG */

	if (which & SSL3_CC_READ)
		{
		if (s->s3->tmp.new_cipher->algorithm2 & TLS1_STREAM_MAC)
			s->mac_flags |= SSL_MAC_FLAG_READ_MAC_STREAM;
			else
			s->mac_flags &= ~SSL_MAC_FLAG_READ_MAC_STREAM;

		if (s->enc_read_ctx != NULL)
			reuse_dd = 1;
		else if ((s->enc_read_ctx=OPENSSL_malloc(sizeof(EVP_CIPHER_CTX))) == NULL)
			goto err;
		else
			/* make sure it's intialized in case we exit later with an error */
			EVP_CIPHER_CTX_init(s->enc_read_ctx);
		dd= s->enc_read_ctx;
		mac_ctx=ssl_replace_hash(&s->read_hash,NULL);
#ifndef OPENSSL_NO_COMP
		if (s->expand != NULL)
			{
			COMP_CTX_free(s->expand);
			s->expand=NULL;
			}
		if (comp != NULL)
			{
			s->expand=COMP_CTX_new(comp->method);
			if (s->expand == NULL)
				{
				SSLerr(SSL_F_TLS1_CHANGE_CIPHER_STATE,SSL_R_COMPRESSION_LIBRARY_ERROR);
				goto err2;
				}
			if (s->s3->rrec.comp == NULL)
				s->s3->rrec.comp=(unsigned char *)
					OPENSSL_malloc(SSL3_RT_MAX_ENCRYPTED_LENGTH);
			if (s->s3->rrec.comp == NULL)
				goto err;
			}
#endif
		/* this is done by dtls1_reset_seq_numbers for DTLS1_VERSION */
 		if (s->version != DTLS1_VERSION)
			memset(&(s->s3->read_sequence[0]),0,8);
		mac_secret= &(s->s3->read_mac_secret[0]);
		mac_secret_size=&(s->s3->read_mac_secret_size);
		}
	else
		{
		if (s->s3->tmp.new_cipher->algorithm2 & TLS1_STREAM_MAC)
			s->mac_flags |= SSL_MAC_FLAG_WRITE_MAC_STREAM;
			else
			s->mac_flags &= ~SSL_MAC_FLAG_WRITE_MAC_STREAM;
		if (s->enc_write_ctx != NULL)
			reuse_dd = 1;
		else if ((s->enc_write_ctx=OPENSSL_malloc(sizeof(EVP_CIPHER_CTX))) == NULL)
			goto err;
		else
			/* make sure it's intialized in case we exit later with an error */
			EVP_CIPHER_CTX_init(s->enc_write_ctx);
		dd= s->enc_write_ctx;
		mac_ctx = ssl_replace_hash(&s->write_hash,NULL);
#ifndef OPENSSL_NO_COMP
		if (s->compress != NULL)
			{
			COMP_CTX_free(s->compress);
			s->compress=NULL;
			}
		if (comp != NULL)
			{
			s->compress=COMP_CTX_new(comp->method);
			if (s->compress == NULL)
				{
				SSLerr(SSL_F_TLS1_CHANGE_CIPHER_STATE,SSL_R_COMPRESSION_LIBRARY_ERROR);
				goto err2;
				}
			}
#endif
		/* this is done by dtls1_reset_seq_numbers for DTLS1_VERSION */
 		if (s->version != DTLS1_VERSION)
			memset(&(s->s3->write_sequence[0]),0,8);
		mac_secret= &(s->s3->write_mac_secret[0]);
		mac_secret_size = &(s->s3->write_mac_secret_size);
		}

	if (reuse_dd)
		EVP_CIPHER_CTX_cleanup(dd);

	p=s->s3->tmp.key_block;
	i=*mac_secret_size=s->s3->tmp.new_mac_secret_size;

	cl=EVP_CIPHER_key_length(c);
	j=is_export ? (cl < SSL_C_EXPORT_KEYLENGTH(s->s3->tmp.new_cipher) ?
	               cl : SSL_C_EXPORT_KEYLENGTH(s->s3->tmp.new_cipher)) : cl;
	/* Was j=(exp)?5:EVP_CIPHER_key_length(c); */
	k=EVP_CIPHER_iv_length(c);
	er1= &(s->s3->client_random[0]);
	er2= &(s->s3->server_random[0]);
	if (	(which == SSL3_CHANGE_CIPHER_CLIENT_WRITE) ||
		(which == SSL3_CHANGE_CIPHER_SERVER_READ))
		{
		ms=  &(p[ 0]); n=i+i;
		key= &(p[ n]); n+=j+j;
		iv=  &(p[ n]); n+=k+k;
		exp_label=(unsigned char *)TLS_MD_CLIENT_WRITE_KEY_CONST;
		exp_label_len=TLS_MD_CLIENT_WRITE_KEY_CONST_SIZE;
		client_write=1;
		}
	else
		{
		n=i;
		ms=  &(p[ n]); n+=i+j;
		key= &(p[ n]); n+=j+k;
		iv=  &(p[ n]); n+=k;
		exp_label=(unsigned char *)TLS_MD_SERVER_WRITE_KEY_CONST;
		exp_label_len=TLS_MD_SERVER_WRITE_KEY_CONST_SIZE;
		client_write=0;
		}

	if (n > s->s3->tmp.key_block_length)
		{
		SSLerr(SSL_F_TLS1_CHANGE_CIPHER_STATE,ERR_R_INTERNAL_ERROR);
		goto err2;
		}

	memcpy(mac_secret,ms,i);
	mac_key = EVP_PKEY_new_mac_key(mac_type, NULL,
			mac_secret,*mac_secret_size);
	EVP_DigestSignInit(mac_ctx,NULL,m,NULL,mac_key);
	EVP_PKEY_free(mac_key);
#ifdef TLS_DEBUG
printf("which = %04X\nmac key=",which);
{ int z; for (z=0; z<i; z++) printf("%02X%c",ms[z],((z+1)%16)?' ':'\n'); }
#endif
	if (is_export)
		{
		/* In here I set both the read and write key/iv to the
		 * same value since only the correct one will be used :-).
		 */
		tls1_PRF(s->s3->tmp.new_cipher->algorithm2,
			 exp_label,exp_label_len,
			 s->s3->client_random,SSL3_RANDOM_SIZE,
			 s->s3->server_random,SSL3_RANDOM_SIZE,
			 NULL,0,NULL,0,
			 key,j,tmp1,tmp2,EVP_CIPHER_key_length(c));
		key=tmp1;

		if (k > 0)
			{
			tls1_PRF(s->s3->tmp.new_cipher->algorithm2,
				 TLS_MD_IV_BLOCK_CONST,TLS_MD_IV_BLOCK_CONST_SIZE,
				 s->s3->client_random,SSL3_RANDOM_SIZE,
				 s->s3->server_random,SSL3_RANDOM_SIZE,
				 NULL,0,NULL,0,
				 empty,0,iv1,iv2,k*2);
			if (client_write)
				iv=iv1;
			else
				iv= &(iv1[k]);
			}
		}

	s->session->key_arg_length=0;
#ifdef KSSL_DEBUG
	{
        int i;
	printf("EVP_CipherInit_ex(dd,c,key=,iv=,which)\n");
	printf("\tkey= "); for (i=0; i<c->key_len; i++) printf("%02x", key[i]);
	printf("\n");
	printf("\t iv= "); for (i=0; i<c->iv_len; i++) printf("%02x", iv[i]);
	printf("\n");
	}
#endif	/* KSSL_DEBUG */

	EVP_CipherInit_ex(dd,c,NULL,key,iv,(which & SSL3_CC_WRITE));
#ifdef TLS_DEBUG
printf("which = %04X\nkey=",which);
{ int z; for (z=0; z<EVP_CIPHER_key_length(c); z++) printf("%02X%c",key[z],((z+1)%16)?' ':'\n'); }
printf("\niv=");
{ int z; for (z=0; z<k; z++) printf("%02X%c",iv[z],((z+1)%16)?' ':'\n'); }
printf("\n");
#endif

	OPENSSL_cleanse(tmp1,sizeof(tmp1));
	OPENSSL_cleanse(tmp2,sizeof(tmp1));
	OPENSSL_cleanse(iv1,sizeof(iv1));
	OPENSSL_cleanse(iv2,sizeof(iv2));
	return(1);
err:
	SSLerr(SSL_F_TLS1_CHANGE_CIPHER_STATE,ERR_R_MALLOC_FAILURE);
err2:
	return(0);
	}
Пример #18
0
BUF_MEM *
retail_mac_des(const BUF_MEM * key, const BUF_MEM * in)
{
    /* ISO 9797-1 algorithm 3 retail mac without any padding */
    BUF_MEM * c_tmp = NULL, *d_tmp = NULL, *mac = NULL, *block = NULL;
    EVP_CIPHER_CTX * ctx = NULL;
    size_t len;

    check(key, "Invalid arguments");

    /* Flawfinder: ignore */
    len = EVP_CIPHER_block_size(EVP_des_cbc());
    check(key->length >= 2*len, "Key too short");

    ctx = EVP_CIPHER_CTX_new();
    if (!ctx)
        goto err;
    EVP_CIPHER_CTX_init(ctx);
    /* Flawfinder: ignore */
    if (!EVP_CipherInit_ex(ctx, EVP_des_cbc(), NULL,
            (unsigned char *) key->data, NULL, 1) ||
            !EVP_CIPHER_CTX_set_padding(ctx, 0))
        goto err;

    /* get last block of des_cbc encrypted input */
    /* Flawfinder: ignore */
    c_tmp = cipher(ctx, EVP_des_cbc(), NULL, NULL, NULL, 1, in);
    if (!c_tmp)
        goto err;
    block = BUF_MEM_create_init(c_tmp->data + c_tmp->length - len, len);

    /* decrypt last block with the rest of the key */
    /* IV is always NULL */
    /* Flawfinder: ignore */
    if (!block || !EVP_CipherInit_ex(ctx, EVP_des_cbc(), NULL,
            (unsigned char *) key->data + len, NULL, 0) ||
            !EVP_CIPHER_CTX_set_padding(ctx, 0))
        goto err;
    /* Flawfinder: ignore */
    d_tmp = cipher(ctx, EVP_des_cbc(), NULL, NULL, NULL, 0, block);

    /* encrypt last block with the first key */
    /* IV is always NULL */
    /* Flawfinder: ignore */
    if (!d_tmp || !EVP_CipherInit_ex(ctx, EVP_des_cbc(), NULL,
            (unsigned char *) key->data, NULL, 1) ||
            !EVP_CIPHER_CTX_set_padding(ctx, 0))
        goto err;
    /* Flawfinder: ignore */
    mac = cipher(ctx, EVP_des_cbc(), NULL, NULL, NULL, 1, d_tmp);

    BUF_MEM_free(block);
    BUF_MEM_free(c_tmp);
    BUF_MEM_free(d_tmp);
    EVP_CIPHER_CTX_free(ctx);

    return mac;

err:
    if (block)
        BUF_MEM_free(block);
    if (c_tmp)
        BUF_MEM_free(c_tmp);
    if (d_tmp)
        BUF_MEM_free(d_tmp);
    if (ctx)
        EVP_CIPHER_CTX_free(ctx);

    return NULL;
}
Пример #19
0
OM_uint32
_gssapi_get_mic_arcfour(OM_uint32 * minor_status,
			const gsskrb5_ctx context_handle,
			krb5_context context,
			gss_qop_t qop_req,
			const gss_buffer_t message_buffer,
			gss_buffer_t message_token,
			krb5_keyblock *key)
{
    krb5_error_code ret;
    int32_t seq_number;
    size_t len, total_len;
    u_char k6_data[16], *p0, *p;
    EVP_CIPHER_CTX rc4_key;

    _gsskrb5_encap_length (22, &len, &total_len, GSS_KRB5_MECHANISM);

    message_token->length = total_len;
    message_token->value  = malloc (total_len);
    if (message_token->value == NULL) {
	*minor_status = ENOMEM;
	return GSS_S_FAILURE;
    }

    p0 = _gssapi_make_mech_header(message_token->value,
				  len,
				  GSS_KRB5_MECHANISM);
    p = p0;

    *p++ = 0x01; /* TOK_ID */
    *p++ = 0x01;
    *p++ = 0x11; /* SGN_ALG */
    *p++ = 0x00;
    *p++ = 0xff; /* Filler */
    *p++ = 0xff;
    *p++ = 0xff;
    *p++ = 0xff;

    p = NULL;

    ret = arcfour_mic_cksum(context,
			    key, KRB5_KU_USAGE_SIGN,
			    p0 + 16, 8,  /* SGN_CKSUM */
			    p0, 8, /* TOK_ID, SGN_ALG, Filer */
			    message_buffer->value, message_buffer->length,
			    NULL, 0);
    if (ret) {
	_gsskrb5_release_buffer(minor_status, message_token);
	*minor_status = ret;
	return GSS_S_FAILURE;
    }

    ret = arcfour_mic_key(context, key,
			  p0 + 16, 8, /* SGN_CKSUM */
			  k6_data, sizeof(k6_data));
    if (ret) {
	_gsskrb5_release_buffer(minor_status, message_token);
	*minor_status = ret;
	return GSS_S_FAILURE;
    }

    HEIMDAL_MUTEX_lock(&context_handle->ctx_id_mutex);
    krb5_auth_con_getlocalseqnumber (context,
				     context_handle->auth_context,
				     &seq_number);
    p = p0 + 8; /* SND_SEQ */
    _gss_mg_encode_be_uint32(seq_number, p);

    krb5_auth_con_setlocalseqnumber (context,
				     context_handle->auth_context,
				     ++seq_number);
    HEIMDAL_MUTEX_unlock(&context_handle->ctx_id_mutex);

    memset (p + 4, (context_handle->more_flags & LOCAL) ? 0 : 0xff, 4);

    EVP_CIPHER_CTX_init(&rc4_key);
    EVP_CipherInit_ex(&rc4_key, EVP_rc4(), NULL, k6_data, NULL, 1);
    EVP_Cipher(&rc4_key, p, p, 8);
    EVP_CIPHER_CTX_cleanup(&rc4_key);

    memset(k6_data, 0, sizeof(k6_data));

    *minor_status = 0;
    return GSS_S_COMPLETE;
}
Пример #20
0
X509_ALGOR *PKCS5_pbe2_set_iv(const EVP_CIPHER *cipher, int iter,
				 unsigned char *salt, int saltlen,
				 unsigned char *aiv, int prf_nid)
{
	X509_ALGOR *scheme = NULL, *kalg = NULL, *ret = NULL;
	int alg_nid, keylen;
	EVP_CIPHER_CTX ctx;
	unsigned char iv[EVP_MAX_IV_LENGTH];
	PBE2PARAM *pbe2 = NULL;
	const ASN1_OBJECT *obj;

	alg_nid = EVP_CIPHER_nid(cipher);
	if(alg_nid == NID_undef) {
		OPENSSL_PUT_ERROR(PKCS8, PKCS5_pbe2_set_iv, PKCS8_R_CIPHER_HAS_NO_OBJECT_IDENTIFIER);
		goto err;
	}
	obj = OBJ_nid2obj(alg_nid);

	if(!(pbe2 = PBE2PARAM_new())) goto merr;

	/* Setup the AlgorithmIdentifier for the encryption scheme */
	scheme = pbe2->encryption;

	scheme->algorithm = (ASN1_OBJECT*) obj;
	if(!(scheme->parameter = ASN1_TYPE_new())) goto merr;

	/* Create random IV */
	if (EVP_CIPHER_iv_length(cipher))
		{
		if (aiv)
			memcpy(iv, aiv, EVP_CIPHER_iv_length(cipher));
		else if (RAND_pseudo_bytes(iv, EVP_CIPHER_iv_length(cipher)) < 0)
  			goto err;
		}

	EVP_CIPHER_CTX_init(&ctx);

	/* Dummy cipherinit to just setup the IV, and PRF */
	if (!EVP_CipherInit_ex(&ctx, cipher, NULL, NULL, iv, 0))
		goto err;
	if(param_to_asn1(&ctx, scheme->parameter) < 0) {
		OPENSSL_PUT_ERROR(PKCS8, PKCS5_pbe2_set_iv, PKCS8_R_ERROR_SETTING_CIPHER_PARAMS);
		EVP_CIPHER_CTX_cleanup(&ctx);
		goto err;
	}
	/* If prf NID unspecified see if cipher has a preference.
	 * An error is OK here: just means use default PRF.
	 */
	if ((prf_nid == -1) && 
	EVP_CIPHER_CTX_ctrl(&ctx, EVP_CTRL_PBE_PRF_NID, 0, &prf_nid) <= 0)
		{
		ERR_clear_error();
		prf_nid = NID_hmacWithSHA1;
		}
	EVP_CIPHER_CTX_cleanup(&ctx);

	/* If its RC2 then we'd better setup the key length */

	if(alg_nid == NID_rc2_cbc)
		keylen = EVP_CIPHER_key_length(cipher);
	else
		keylen = -1;

	/* Setup keyfunc */

	X509_ALGOR_free(pbe2->keyfunc);

	pbe2->keyfunc = PKCS5_pbkdf2_set(iter, salt, saltlen, prf_nid, keylen);

	if (!pbe2->keyfunc)
		goto merr;

	/* Now set up top level AlgorithmIdentifier */

	if(!(ret = X509_ALGOR_new())) goto merr;
	if(!(ret->parameter = ASN1_TYPE_new())) goto merr;

	ret->algorithm = (ASN1_OBJECT*) OBJ_nid2obj(NID_pbes2);

	/* Encode PBE2PARAM into parameter */

	if(!ASN1_item_pack(pbe2, ASN1_ITEM_rptr(PBE2PARAM),
				 &ret->parameter->value.sequence)) goto merr;
	ret->parameter->type = V_ASN1_SEQUENCE;

	PBE2PARAM_free(pbe2);
	pbe2 = NULL;

	return ret;

	merr:
	OPENSSL_PUT_ERROR(PKCS8, PKCS5_pbe2_set_iv, ERR_R_MALLOC_FAILURE);

	err:
	PBE2PARAM_free(pbe2);
	/* Note 'scheme' is freed as part of pbe2 */
	X509_ALGOR_free(kalg);
	X509_ALGOR_free(ret);

	return NULL;

}
Пример #21
0
OM_uint32
_gssapi_wrap_arcfour(OM_uint32 * minor_status,
		     const gsskrb5_ctx context_handle,
		     krb5_context context,
		     int conf_req_flag,
		     gss_qop_t qop_req,
		     const gss_buffer_t input_message_buffer,
		     int * conf_state,
		     gss_buffer_t output_message_buffer,
		     krb5_keyblock *key)
{
    u_char Klocaldata[16], k6_data[16], *p, *p0;
    size_t len, total_len, datalen;
    krb5_keyblock Klocal;
    krb5_error_code ret;
    int32_t seq_number;

    if (conf_state)
	*conf_state = 0;

    datalen = input_message_buffer->length;

    if (IS_DCE_STYLE(context_handle)) {
	len = GSS_ARCFOUR_WRAP_TOKEN_SIZE;
	_gssapi_encap_length(len, &len, &total_len, GSS_KRB5_MECHANISM);
	total_len += datalen;
    } else {
	datalen += 1; /* padding */
	len = datalen + GSS_ARCFOUR_WRAP_TOKEN_SIZE;
	_gssapi_encap_length(len, &len, &total_len, GSS_KRB5_MECHANISM);
    }

    output_message_buffer->length = total_len;
    output_message_buffer->value  = malloc (total_len);
    if (output_message_buffer->value == NULL) {
	*minor_status = ENOMEM;
	return GSS_S_FAILURE;
    }

    p0 = _gssapi_make_mech_header(output_message_buffer->value,
				  len,
				  GSS_KRB5_MECHANISM);
    p = p0;

    *p++ = 0x02; /* TOK_ID */
    *p++ = 0x01;
    *p++ = 0x11; /* SGN_ALG */
    *p++ = 0x00;
    if (conf_req_flag) {
	*p++ = 0x10; /* SEAL_ALG */
	*p++ = 0x00;
    } else {
	*p++ = 0xff; /* SEAL_ALG */
	*p++ = 0xff;
    }
    *p++ = 0xff; /* Filler */
    *p++ = 0xff;

    p = NULL;

    HEIMDAL_MUTEX_lock(&context_handle->ctx_id_mutex);
    krb5_auth_con_getlocalseqnumber (context,
				     context_handle->auth_context,
				     &seq_number);

    _gss_mg_encode_be_uint32(seq_number, p0 + 8);

    krb5_auth_con_setlocalseqnumber (context,
				     context_handle->auth_context,
				     ++seq_number);
    HEIMDAL_MUTEX_unlock(&context_handle->ctx_id_mutex);

    memset (p0 + 8 + 4,
	    (context_handle->more_flags & LOCAL) ? 0 : 0xff,
	    4);

    krb5_generate_random_block(p0 + 24, 8); /* fill in Confounder */

    /* p points to data */
    p = p0 + GSS_ARCFOUR_WRAP_TOKEN_SIZE;
    memcpy(p, input_message_buffer->value, input_message_buffer->length);

    if (!IS_DCE_STYLE(context_handle))
	p[input_message_buffer->length] = 1; /* padding */

    ret = arcfour_mic_cksum(context,
			    key, KRB5_KU_USAGE_SEAL,
			    p0 + 16, 8, /* SGN_CKSUM */
			    p0, 8, /* TOK_ID, SGN_ALG, SEAL_ALG, Filler */
			    p0 + 24, 8, /* Confounder */
			    p0 + GSS_ARCFOUR_WRAP_TOKEN_SIZE,
			    datalen);
    if (ret) {
	*minor_status = ret;
	_gsskrb5_release_buffer(minor_status, output_message_buffer);
	return GSS_S_FAILURE;
    }

    {
	int i;

	Klocal.keytype = key->keytype;
	Klocal.keyvalue.data = Klocaldata;
	Klocal.keyvalue.length = sizeof(Klocaldata);

	for (i = 0; i < 16; i++)
	    Klocaldata[i] = ((u_char *)key->keyvalue.data)[i] ^ 0xF0;
    }
    ret = arcfour_mic_key(context, &Klocal,
			  p0 + 8, 4, /* SND_SEQ */
			  k6_data, sizeof(k6_data));
    memset(Klocaldata, 0, sizeof(Klocaldata));
    if (ret) {
	_gsskrb5_release_buffer(minor_status, output_message_buffer);
	*minor_status = ret;
	return GSS_S_FAILURE;
    }


    if(conf_req_flag) {
	EVP_CIPHER_CTX rc4_key;

	EVP_CIPHER_CTX_init(&rc4_key);
	EVP_CipherInit_ex(&rc4_key, EVP_rc4(), NULL, k6_data, NULL, 1);
	EVP_Cipher(&rc4_key, p0 + 24, p0 + 24, 8 + datalen);
	EVP_CIPHER_CTX_cleanup(&rc4_key);
    }
    memset(k6_data, 0, sizeof(k6_data));

    ret = arcfour_mic_key(context, key,
			  p0 + 16, 8, /* SGN_CKSUM */
			  k6_data, sizeof(k6_data));
    if (ret) {
	_gsskrb5_release_buffer(minor_status, output_message_buffer);
	*minor_status = ret;
	return GSS_S_FAILURE;
    }

    {
	EVP_CIPHER_CTX rc4_key;

	EVP_CIPHER_CTX_init(&rc4_key);
	EVP_CipherInit_ex(&rc4_key, EVP_rc4(), NULL, k6_data, NULL, 1);
	EVP_Cipher(&rc4_key, p0 + 8, p0 + 8 /* SND_SEQ */, 8);
	EVP_CIPHER_CTX_cleanup(&rc4_key);
	memset(k6_data, 0, sizeof(k6_data));
    }

    if (conf_state)
	*conf_state = conf_req_flag;

    *minor_status = 0;
    return GSS_S_COMPLETE;
}
Пример #22
0
static long enc_ctrl(BIO *b, int cmd, long num, void *ptr)
  {
  BIO *dbio;
  BIO_ENC_CTX *ctx,*dctx;
  long ret=1;
  int i;
  EVP_CIPHER_CTX **c_ctx;

  ctx=(BIO_ENC_CTX *)b->ptr;

  switch (cmd)
    {
  case BIO_CTRL_RESET:
    ctx->ok=1;
    ctx->finished=0;
    EVP_CipherInit_ex(&(ctx->cipher),NULL,NULL,NULL,NULL,
      ctx->cipher.encrypt);
    ret=BIO_ctrl(b->next_bio,cmd,num,ptr);
    break;
  case BIO_CTRL_EOF:  /* More to read */
    if (ctx->cont <= 0)
      ret=1;
    else
      ret=BIO_ctrl(b->next_bio,cmd,num,ptr);
    break;
  case BIO_CTRL_WPENDING:
    ret=ctx->buf_len-ctx->buf_off;
    if (ret <= 0)
      ret=BIO_ctrl(b->next_bio,cmd,num,ptr);
    break;
  case BIO_CTRL_PENDING: /* More to read in buffer */
    ret=ctx->buf_len-ctx->buf_off;
    if (ret <= 0)
      ret=BIO_ctrl(b->next_bio,cmd,num,ptr);
    break;
  case BIO_CTRL_FLUSH:
    /* do a final write */
again:
    while (ctx->buf_len != ctx->buf_off)
      {
      i=enc_write(b,NULL,0);
      if (i < 0)
        return i;
      }

    if (!ctx->finished)
      {
      ctx->finished=1;
      ctx->buf_off=0;
      ret=EVP_CipherFinal_ex(&(ctx->cipher),
        (unsigned char *)ctx->buf,
        &(ctx->buf_len));
      ctx->ok=(int)ret;
      if (ret <= 0) break;

      /* push out the bytes */
      goto again;
      }
    
    /* Finally flush the underlying BIO */
    ret=BIO_ctrl(b->next_bio,cmd,num,ptr);
    break;
  case BIO_C_GET_CIPHER_STATUS:
    ret=(long)ctx->ok;
    break;
  case BIO_C_DO_STATE_MACHINE:
    BIO_clear_retry_flags(b);
    ret=BIO_ctrl(b->next_bio,cmd,num,ptr);
    BIO_copy_next_retry(b);
    break;
  case BIO_C_GET_CIPHER_CTX:
    c_ctx=(EVP_CIPHER_CTX **)ptr;
    (*c_ctx)= &(ctx->cipher);
    b->init=1;
    break;
  case BIO_CTRL_DUP:
    dbio=(BIO *)ptr;
    dctx=(BIO_ENC_CTX *)dbio->ptr;
    memcpy(&(dctx->cipher),&(ctx->cipher),sizeof(ctx->cipher));
    dbio->init=1;
    break;
  default:
    ret=BIO_ctrl(b->next_bio,cmd,num,ptr);
    break;
    }
  return(ret);
  }
Пример #23
0
BIO *
PKCS7_dataInit(PKCS7 *p7, BIO *bio)
{
	int i;
	BIO *out = NULL, *btmp = NULL;
	X509_ALGOR *xa = NULL;
	const EVP_CIPHER *evp_cipher = NULL;
	STACK_OF(X509_ALGOR) *md_sk = NULL;
	STACK_OF(PKCS7_RECIP_INFO) *rsk = NULL;
	X509_ALGOR *xalg = NULL;
	PKCS7_RECIP_INFO *ri = NULL;
	ASN1_OCTET_STRING *os = NULL;

	i = OBJ_obj2nid(p7->type);
	p7->state = PKCS7_S_HEADER;

	switch (i) {
	case NID_pkcs7_signed:
		md_sk = p7->d.sign->md_algs;
		os = PKCS7_get_octet_string(p7->d.sign->contents);
		break;
	case NID_pkcs7_signedAndEnveloped:
		rsk = p7->d.signed_and_enveloped->recipientinfo;
		md_sk = p7->d.signed_and_enveloped->md_algs;
		xalg = p7->d.signed_and_enveloped->enc_data->algorithm;
		evp_cipher = p7->d.signed_and_enveloped->enc_data->cipher;
		if (evp_cipher == NULL) {
			PKCS7err(PKCS7_F_PKCS7_DATAINIT,
			    PKCS7_R_CIPHER_NOT_INITIALIZED);
			goto err;
		}
		break;
	case NID_pkcs7_enveloped:
		rsk = p7->d.enveloped->recipientinfo;
		xalg = p7->d.enveloped->enc_data->algorithm;
		evp_cipher = p7->d.enveloped->enc_data->cipher;
		if (evp_cipher == NULL) {
			PKCS7err(PKCS7_F_PKCS7_DATAINIT,
			    PKCS7_R_CIPHER_NOT_INITIALIZED);
			goto err;
		}
		break;
	case NID_pkcs7_digest:
		xa = p7->d.digest->md;
		os = PKCS7_get_octet_string(p7->d.digest->contents);
		break;
	case NID_pkcs7_data:
		break;
	default:
		PKCS7err(PKCS7_F_PKCS7_DATAINIT,
		    PKCS7_R_UNSUPPORTED_CONTENT_TYPE);
		goto err;
	}

	for (i = 0; i < sk_X509_ALGOR_num(md_sk); i++)
		if (!PKCS7_bio_add_digest(&out, sk_X509_ALGOR_value(md_sk, i)))
			goto err;

	if (xa && !PKCS7_bio_add_digest(&out, xa))
		goto err;

	if (evp_cipher != NULL) {
		unsigned char key[EVP_MAX_KEY_LENGTH];
		unsigned char iv[EVP_MAX_IV_LENGTH];
		int keylen, ivlen;
		EVP_CIPHER_CTX *ctx;

		if ((btmp = BIO_new(BIO_f_cipher())) == NULL) {
			PKCS7err(PKCS7_F_PKCS7_DATAINIT, ERR_R_BIO_LIB);
			goto err;
		}
		BIO_get_cipher_ctx(btmp, &ctx);
		keylen = EVP_CIPHER_key_length(evp_cipher);
		ivlen = EVP_CIPHER_iv_length(evp_cipher);
		xalg->algorithm = OBJ_nid2obj(EVP_CIPHER_type(evp_cipher));
		if (ivlen > 0)
			if (RAND_pseudo_bytes(iv, ivlen) <= 0)
				goto err;
		if (EVP_CipherInit_ex(ctx, evp_cipher, NULL, NULL,
		    NULL, 1) <= 0)
			goto err;
		if (EVP_CIPHER_CTX_rand_key(ctx, key) <= 0)
			goto err;
		if (EVP_CipherInit_ex(ctx, NULL, NULL, key, iv, 1) <= 0)
			goto err;

		if (ivlen > 0) {
			if (xalg->parameter == NULL) {
				xalg->parameter = ASN1_TYPE_new();
				if (xalg->parameter == NULL)
					goto err;
			}
			if (EVP_CIPHER_param_to_asn1(ctx, xalg->parameter) < 0)
				goto err;
		}

		/* Lets do the pub key stuff :-) */
		for (i = 0; i < sk_PKCS7_RECIP_INFO_num(rsk); i++) {
			ri = sk_PKCS7_RECIP_INFO_value(rsk, i);
			if (pkcs7_encode_rinfo(ri, key, keylen) <= 0)
				goto err;
		}
		OPENSSL_cleanse(key, keylen);

		if (out == NULL)
			out = btmp;
		else
			BIO_push(out, btmp);
		btmp = NULL;
	}

	if (bio == NULL) {
		if (PKCS7_is_detached(p7))
			bio = BIO_new(BIO_s_null());
		else if (os && os->length > 0)
			bio = BIO_new_mem_buf(os->data, os->length);
		if (bio == NULL) {
			bio = BIO_new(BIO_s_mem());
			if (bio == NULL)
				goto err;
			BIO_set_mem_eof_return(bio, 0);
		}
	}
	if (out)
		BIO_push(out, bio);
	else
		out = bio;
	bio = NULL;
	if (0) {
err:
		if (out != NULL)
			BIO_free_all(out);
		if (btmp != NULL)
			BIO_free_all(btmp);
		out = NULL;
	}
	return (out);
}
int PKCS5_PBE_keyivgen(EVP_CIPHER_CTX *cctx, const char *pass, int passlen,
			 ASN1_TYPE *param, const EVP_CIPHER *cipher, const EVP_MD *md,
			 int en_de)
{
	EVP_MD_CTX ctx;
	unsigned char md_tmp[EVP_MAX_MD_SIZE];
	unsigned char key[EVP_MAX_KEY_LENGTH], iv[EVP_MAX_IV_LENGTH];
	int i;
	PBEPARAM *pbe;
	int saltlen, iter;
	unsigned char *salt;
	const unsigned char *pbuf;
	int mdsize;

	/* Extract useful info from parameter */
	if (param == NULL || param->type != V_ASN1_SEQUENCE ||
	    param->value.sequence == NULL) {
		EVPerr(EVP_F_PKCS5_PBE_KEYIVGEN,EVP_R_DECODE_ERROR);
		return 0;
	}

	pbuf = param->value.sequence->data;
	if (!(pbe = d2i_PBEPARAM(NULL, &pbuf, param->value.sequence->length))) {
		EVPerr(EVP_F_PKCS5_PBE_KEYIVGEN,EVP_R_DECODE_ERROR);
		return 0;
	}

	if (!pbe->iter) iter = 1;
	else iter = ASN1_INTEGER_get (pbe->iter);
	salt = pbe->salt->data;
	saltlen = pbe->salt->length;

	if(!pass) passlen = 0;
	else if(passlen == -1) passlen = TINYCLR_SSL_STRLEN(pass);

	EVP_MD_CTX_init(&ctx);
	EVP_DigestInit_ex(&ctx, md, NULL);
	EVP_DigestUpdate(&ctx, pass, passlen);
	EVP_DigestUpdate(&ctx, salt, saltlen);
	PBEPARAM_free(pbe);
	EVP_DigestFinal_ex(&ctx, md_tmp, NULL);
	mdsize = EVP_MD_size(md);
	if (mdsize < 0)
	    return 0;
	for (i = 1; i < iter; i++) {
		EVP_DigestInit_ex(&ctx, md, NULL);
		EVP_DigestUpdate(&ctx, md_tmp, mdsize);
		EVP_DigestFinal_ex (&ctx, md_tmp, NULL);
	}
	EVP_MD_CTX_cleanup(&ctx);
	TINYCLR_SSL_ASSERT(EVP_CIPHER_key_length(cipher) <= (int)sizeof(md_tmp));
	TINYCLR_SSL_MEMCPY(key, md_tmp, EVP_CIPHER_key_length(cipher));
	TINYCLR_SSL_ASSERT(EVP_CIPHER_iv_length(cipher) <= 16);
	TINYCLR_SSL_MEMCPY(iv, md_tmp + (16 - EVP_CIPHER_iv_length(cipher)),
						 EVP_CIPHER_iv_length(cipher));
	EVP_CipherInit_ex(cctx, cipher, NULL, key, iv, en_de);
	OPENSSL_cleanse(md_tmp, EVP_MAX_MD_SIZE);
	OPENSSL_cleanse(key, EVP_MAX_KEY_LENGTH);
	OPENSSL_cleanse(iv, EVP_MAX_IV_LENGTH);
	return 1;
}
Пример #25
0
int PKCS5_PBE_keyivgen(EVP_CIPHER_CTX *cctx, const char *pass, int passlen,
                       ASN1_TYPE *param, const EVP_CIPHER *cipher,
                       const EVP_MD *md, int en_de)
{
    EVP_MD_CTX *ctx;
    unsigned char md_tmp[EVP_MAX_MD_SIZE];
    unsigned char key[EVP_MAX_KEY_LENGTH], iv[EVP_MAX_IV_LENGTH];
    int i;
    PBEPARAM *pbe;
    int saltlen, iter;
    unsigned char *salt;
    int mdsize;
    int rv = 0;

    /* Extract useful info from parameter */
    if (param == NULL || param->type != V_ASN1_SEQUENCE ||
        param->value.sequence == NULL) {
        EVPerr(EVP_F_PKCS5_PBE_KEYIVGEN, EVP_R_DECODE_ERROR);
        return 0;
    }

    pbe = ASN1_TYPE_unpack_sequence(ASN1_ITEM_rptr(PBEPARAM), param);
    if (pbe == NULL) {
        EVPerr(EVP_F_PKCS5_PBE_KEYIVGEN, EVP_R_DECODE_ERROR);
        return 0;
    }

    if (!pbe->iter)
        iter = 1;
    else
        iter = ASN1_INTEGER_get(pbe->iter);
    salt = pbe->salt->data;
    saltlen = pbe->salt->length;

    if (!pass)
        passlen = 0;
    else if (passlen == -1)
        passlen = strlen(pass);

    ctx = EVP_MD_CTX_new();
    if (ctx == NULL) {
        EVPerr(EVP_F_PKCS5_PBE_KEYIVGEN, ERR_R_MALLOC_FAILURE);
        goto err;
    }

    if (!EVP_DigestInit_ex(ctx, md, NULL))
        goto err;
    if (!EVP_DigestUpdate(ctx, pass, passlen))
        goto err;
    if (!EVP_DigestUpdate(ctx, salt, saltlen))
        goto err;
    PBEPARAM_free(pbe);
    if (!EVP_DigestFinal_ex(ctx, md_tmp, NULL))
        goto err;
    mdsize = EVP_MD_size(md);
    if (mdsize < 0)
        return 0;
    for (i = 1; i < iter; i++) {
        if (!EVP_DigestInit_ex(ctx, md, NULL))
            goto err;
        if (!EVP_DigestUpdate(ctx, md_tmp, mdsize))
            goto err;
        if (!EVP_DigestFinal_ex(ctx, md_tmp, NULL))
            goto err;
    }
    OPENSSL_assert(EVP_CIPHER_key_length(cipher) <= (int)sizeof(md_tmp));
    memcpy(key, md_tmp, EVP_CIPHER_key_length(cipher));
    OPENSSL_assert(EVP_CIPHER_iv_length(cipher) <= 16);
    memcpy(iv, md_tmp + (16 - EVP_CIPHER_iv_length(cipher)),
           EVP_CIPHER_iv_length(cipher));
    if (!EVP_CipherInit_ex(cctx, cipher, NULL, key, iv, en_de))
        goto err;
    OPENSSL_cleanse(md_tmp, EVP_MAX_MD_SIZE);
    OPENSSL_cleanse(key, EVP_MAX_KEY_LENGTH);
    OPENSSL_cleanse(iv, EVP_MAX_IV_LENGTH);
    rv = 1;
 err:
    EVP_MD_CTX_free(ctx);
    return rv;
}
Пример #26
0
int MAIN(int argc, char **argv)
	{
#ifndef OPENSSL_NO_ENGINE
	ENGINE *e = NULL;
#endif
	static const char magic[]="Salted__";
	char mbuf[sizeof magic-1];
	char *strbuf=NULL;
	unsigned char *buff=NULL,*bufsize=NULL;
	int bsize=BSIZE,verbose=0;
	int ret=1,inl;
	int nopad = 0;
	unsigned char key[EVP_MAX_KEY_LENGTH],iv[EVP_MAX_IV_LENGTH];
	unsigned char salt[PKCS5_SALT_LEN];
	char *str=NULL, *passarg = NULL, *pass = NULL;
	char *hkey=NULL,*hiv=NULL,*hsalt = NULL;
	char *md=NULL;
	int enc=1,printkey=0,i,base64=0;
	int debug=0,olb64=0,nosalt=0;
	const EVP_CIPHER *cipher=NULL,*c;
	EVP_CIPHER_CTX *ctx = NULL;
	char *inf=NULL,*outf=NULL;
	BIO *in=NULL,*out=NULL,*b64=NULL,*benc=NULL,*rbio=NULL,*wbio=NULL;
#define PROG_NAME_SIZE  39
	char pname[PROG_NAME_SIZE+1];
#ifndef OPENSSL_NO_ENGINE
	char *engine = NULL;
#endif
	const EVP_MD *dgst=NULL;
	int non_fips_allow = 0;

	apps_startup();

	if (bio_err == NULL)
		if ((bio_err=BIO_new(BIO_s_file())) != NULL)
			BIO_set_fp(bio_err,stderr,BIO_NOCLOSE|BIO_FP_TEXT);

	if (!load_config(bio_err, NULL))
		goto end;

	/* first check the program name */
	program_name(argv[0],pname,sizeof pname);
	if (strcmp(pname,"base64") == 0)
		base64=1;

	cipher=EVP_get_cipherbyname(pname);
	if (!base64 && (cipher == NULL) && (strcmp(pname,"enc") != 0))
		{
		BIO_printf(bio_err,"%s is an unknown cipher\n",pname);
		goto bad;
		}

	argc--;
	argv++;
	while (argc >= 1)
		{
		if	(strcmp(*argv,"-e") == 0)
			enc=1;
		else if (strcmp(*argv,"-in") == 0)
			{
			if (--argc < 1) goto bad;
			inf= *(++argv);
			}
		else if (strcmp(*argv,"-out") == 0)
			{
			if (--argc < 1) goto bad;
			outf= *(++argv);
			}
		else if (strcmp(*argv,"-pass") == 0)
			{
			if (--argc < 1) goto bad;
			passarg= *(++argv);
			}
#ifndef OPENSSL_NO_ENGINE
		else if (strcmp(*argv,"-engine") == 0)
			{
			if (--argc < 1) goto bad;
			engine= *(++argv);
			}
#endif
		else if	(strcmp(*argv,"-d") == 0)
			enc=0;
		else if	(strcmp(*argv,"-p") == 0)
			printkey=1;
		else if	(strcmp(*argv,"-v") == 0)
			verbose=1;
		else if	(strcmp(*argv,"-nopad") == 0)
			nopad=1;
		else if	(strcmp(*argv,"-salt") == 0)
			nosalt=0;
		else if	(strcmp(*argv,"-nosalt") == 0)
			nosalt=1;
		else if	(strcmp(*argv,"-debug") == 0)
			debug=1;
		else if	(strcmp(*argv,"-P") == 0)
			printkey=2;
		else if	(strcmp(*argv,"-A") == 0)
			olb64=1;
		else if	(strcmp(*argv,"-a") == 0)
			base64=1;
		else if	(strcmp(*argv,"-base64") == 0)
			base64=1;
		else if (strcmp(*argv,"-bufsize") == 0)
			{
			if (--argc < 1) goto bad;
			bufsize=(unsigned char *)*(++argv);
			}
		else if (strcmp(*argv,"-k") == 0)
			{
			if (--argc < 1) goto bad;
			str= *(++argv);
			}
		else if (strcmp(*argv,"-kfile") == 0)
			{
			static char buf[128];
			FILE *infile;
			char *file;

			if (--argc < 1) goto bad;
			file= *(++argv);
			infile=fopen(file,"r");
			if (infile == NULL)
				{
				BIO_printf(bio_err,"unable to read key from '%s'\n",
					file);
				goto bad;
				}
			buf[0]='\0';
			fgets(buf,sizeof buf,infile);
			fclose(infile);
			i=strlen(buf);
			if ((i > 0) &&
				((buf[i-1] == '\n') || (buf[i-1] == '\r')))
				buf[--i]='\0';
			if ((i > 0) &&
				((buf[i-1] == '\n') || (buf[i-1] == '\r')))
				buf[--i]='\0';
			if (i < 1)
				{
				BIO_printf(bio_err,"zero length password\n");
				goto bad;
				}
			str=buf;
			}
		else if (strcmp(*argv,"-K") == 0)
			{
			if (--argc < 1) goto bad;
			hkey= *(++argv);
			}
		else if (strcmp(*argv,"-S") == 0)
			{
			if (--argc < 1) goto bad;
			hsalt= *(++argv);
			}
		else if (strcmp(*argv,"-iv") == 0)
			{
			if (--argc < 1) goto bad;
			hiv= *(++argv);
			}
		else if (strcmp(*argv,"-md") == 0)
			{
			if (--argc < 1) goto bad;
			md= *(++argv);
			}
		else if (strcmp(*argv,"-non-fips-allow") == 0)
			non_fips_allow = 1;
		else if	((argv[0][0] == '-') &&
			((c=EVP_get_cipherbyname(&(argv[0][1]))) != NULL))
			{
			cipher=c;
			}
		else if (strcmp(*argv,"-none") == 0)
			cipher=NULL;
		else
			{
			BIO_printf(bio_err,"unknown option '%s'\n",*argv);
bad:
			BIO_printf(bio_err,"options are\n");
			BIO_printf(bio_err,"%-14s input file\n","-in <file>");
			BIO_printf(bio_err,"%-14s output file\n","-out <file>");
			BIO_printf(bio_err,"%-14s pass phrase source\n","-pass <arg>");
			BIO_printf(bio_err,"%-14s encrypt\n","-e");
			BIO_printf(bio_err,"%-14s decrypt\n","-d");
			BIO_printf(bio_err,"%-14s base64 encode/decode, depending on encryption flag\n","-a/-base64");
			BIO_printf(bio_err,"%-14s passphrase is the next argument\n","-k");
			BIO_printf(bio_err,"%-14s passphrase is the first line of the file argument\n","-kfile");
			BIO_printf(bio_err,"%-14s the next argument is the md to use to create a key\n","-md");
			BIO_printf(bio_err,"%-14s   from a passphrase.  One of md2, md5, sha or sha1\n","");
			BIO_printf(bio_err,"%-14s key/iv in hex is the next argument\n","-K/-iv");
			BIO_printf(bio_err,"%-14s print the iv/key (then exit if -P)\n","-[pP]");
			BIO_printf(bio_err,"%-14s buffer size\n","-bufsize <n>");
#ifndef OPENSSL_NO_ENGINE
			BIO_printf(bio_err,"%-14s use engine e, possibly a hardware device.\n","-engine e");
#endif

			BIO_printf(bio_err,"Cipher Types\n");
			OBJ_NAME_do_all_sorted(OBJ_NAME_TYPE_CIPHER_METH,
					       show_ciphers,
					       bio_err);
			BIO_printf(bio_err,"\n");

			goto end;
			}
		argc--;
		argv++;
		}

#ifndef OPENSSL_NO_ENGINE
        e = setup_engine(bio_err, engine, 0);
#endif

	if (md && (dgst=EVP_get_digestbyname(md)) == NULL)
		{
		BIO_printf(bio_err,"%s is an unsupported message digest type\n",md);
		goto end;
		}

	if (dgst == NULL)
		{
		if (in_FIPS_mode)
			dgst = EVP_sha1();
		else
			dgst = EVP_md5();
		}

	if (bufsize != NULL)
		{
		unsigned long n;

		for (n=0; *bufsize; bufsize++)
			{
			i= *bufsize;
			if ((i <= '9') && (i >= '0'))
				n=n*10+i-'0';
			else if (i == 'k')
				{
				n*=1024;
				bufsize++;
				break;
				}
			}
		if (*bufsize != '\0')
			{
			BIO_printf(bio_err,"invalid 'bufsize' specified.\n");
			goto end;
			}

		/* It must be large enough for a base64 encoded line */
		if (base64 && n < 80) n=80;

		bsize=(int)n;
		if (verbose) BIO_printf(bio_err,"bufsize=%d\n",bsize);
		}

	strbuf=OPENSSL_malloc(SIZE);
	buff=(unsigned char *)OPENSSL_malloc(EVP_ENCODE_LENGTH(bsize));
	if ((buff == NULL) || (strbuf == NULL))
		{
		BIO_printf(bio_err,"OPENSSL_malloc failure %ld\n",(long)EVP_ENCODE_LENGTH(bsize));
		goto end;
		}

	in=BIO_new(BIO_s_file());
	out=BIO_new(BIO_s_file());
	if ((in == NULL) || (out == NULL))
		{
		ERR_print_errors(bio_err);
		goto end;
		}
	if (debug)
		{
		BIO_set_callback(in,BIO_debug_callback);
		BIO_set_callback(out,BIO_debug_callback);
		BIO_set_callback_arg(in,(char *)bio_err);
		BIO_set_callback_arg(out,(char *)bio_err);
		}

	if (inf == NULL)
	        {
		if (bufsize != NULL)
			setvbuf(stdin, (char *)NULL, _IONBF, 0);
		BIO_set_fp(in,stdin,BIO_NOCLOSE);
	        }
	else
		{
		if (BIO_read_filename(in,inf) <= 0)
			{
			perror(inf);
			goto end;
			}
		}

	if(!str && passarg) {
		if(!app_passwd(bio_err, passarg, NULL, &pass, NULL)) {
			BIO_printf(bio_err, "Error getting password\n");
			goto end;
		}
		str = pass;
	}

	if ((str == NULL) && (cipher != NULL) && (hkey == NULL))
		{
		for (;;)
			{
			char buf[200];

			BIO_snprintf(buf,sizeof buf,"enter %s %s password:"******"encryption":"decryption");
			strbuf[0]='\0';
			i=EVP_read_pw_string((char *)strbuf,SIZE,buf,enc);
			if (i == 0)
				{
				if (strbuf[0] == '\0')
					{
					ret=1;
					goto end;
					}
				str=strbuf;
				break;
				}
			if (i < 0)
				{
				BIO_printf(bio_err,"bad password read\n");
				goto end;
				}
			}
		}


	if (outf == NULL)
		{
		BIO_set_fp(out,stdout,BIO_NOCLOSE);
		if (bufsize != NULL)
			setvbuf(stdout, (char *)NULL, _IONBF, 0);
#ifdef OPENSSL_SYS_VMS
		{
		BIO *tmpbio = BIO_new(BIO_f_linebuffer());
		out = BIO_push(tmpbio, out);
		}
#endif
		}
	else
		{
		if (BIO_write_filename(out,outf) <= 0)
			{
			perror(outf);
			goto end;
			}
		}

	rbio=in;
	wbio=out;

	if (base64)
		{
		if ((b64=BIO_new(BIO_f_base64())) == NULL)
			goto end;
		if (debug)
			{
			BIO_set_callback(b64,BIO_debug_callback);
			BIO_set_callback_arg(b64,(char *)bio_err);
			}
		if (olb64)
			BIO_set_flags(b64,BIO_FLAGS_BASE64_NO_NL);
		if (enc)
			wbio=BIO_push(b64,wbio);
		else
			rbio=BIO_push(b64,rbio);
		}

	if (cipher != NULL)
		{
		/* Note that str is NULL if a key was passed on the command
		 * line, so we get no salt in that case. Is this a bug?
		 */
		if (str != NULL)
			{
			/* Salt handling: if encrypting generate a salt and
			 * write to output BIO. If decrypting read salt from
			 * input BIO.
			 */
			unsigned char *sptr;
			if(nosalt) sptr = NULL;
			else {
				if(enc) {
					if(hsalt) {
						if(!set_hex(hsalt,salt,sizeof salt)) {
							BIO_printf(bio_err,
								"invalid hex salt value\n");
							goto end;
						}
					} else if (RAND_pseudo_bytes(salt, sizeof salt) < 0)
						goto end;
					/* If -P option then don't bother writing */
					if((printkey != 2)
					   && (BIO_write(wbio,magic,
							 sizeof magic-1) != sizeof magic-1
					       || BIO_write(wbio,
							    (char *)salt,
							    sizeof salt) != sizeof salt)) {
						BIO_printf(bio_err,"error writing output file\n");
						goto end;
					}
				} else if(BIO_read(rbio,mbuf,sizeof mbuf) != sizeof mbuf
					  || BIO_read(rbio,
						      (unsigned char *)salt,
				    sizeof salt) != sizeof salt) {
					BIO_printf(bio_err,"error reading input file\n");
					goto end;
				} else if(memcmp(mbuf,magic,sizeof magic-1)) {
				    BIO_printf(bio_err,"bad magic number\n");
				    goto end;
				}

				sptr = salt;
			}

			EVP_BytesToKey(cipher,dgst,sptr,
				(unsigned char *)str,
				strlen(str),1,key,iv);
			/* zero the complete buffer or the string
			 * passed from the command line
			 * bug picked up by
			 * Larry J. Hughes Jr. <*****@*****.**> */
			if (str == strbuf)
				OPENSSL_cleanse(str,SIZE);
			else
				OPENSSL_cleanse(str,strlen(str));
			}
		if ((hiv != NULL) && !set_hex(hiv,iv,sizeof iv))
			{
			BIO_printf(bio_err,"invalid hex iv value\n");
			goto end;
			}
		if ((hiv == NULL) && (str == NULL)
		    && EVP_CIPHER_iv_length(cipher) != 0)
			{
			/* No IV was explicitly set and no IV was generated
			 * during EVP_BytesToKey. Hence the IV is undefined,
			 * making correct decryption impossible. */
			BIO_printf(bio_err, "iv undefined\n");
			goto end;
			}
		if ((hkey != NULL) && !set_hex(hkey,key,sizeof key))
			{
			BIO_printf(bio_err,"invalid hex key value\n");
			goto end;
			}

		if ((benc=BIO_new(BIO_f_cipher())) == NULL)
			goto end;

		/* Since we may be changing parameters work on the encryption
		 * context rather than calling BIO_set_cipher().
		 */

		BIO_get_cipher_ctx(benc, &ctx);

		if (non_fips_allow)
			EVP_CIPHER_CTX_set_flags(ctx,
				EVP_CIPH_FLAG_NON_FIPS_ALLOW);

		if (!EVP_CipherInit_ex(ctx, cipher, NULL, NULL, NULL, enc))
			{
			BIO_printf(bio_err, "Error setting cipher %s\n",
				EVP_CIPHER_name(cipher));
			ERR_print_errors(bio_err);
			goto end;
			}

		if (nopad)
			EVP_CIPHER_CTX_set_padding(ctx, 0);

		if (!EVP_CipherInit_ex(ctx, NULL, NULL, key, iv, enc))
			{
			BIO_printf(bio_err, "Error setting cipher %s\n",
				EVP_CIPHER_name(cipher));
			ERR_print_errors(bio_err);
			goto end;
			}

		if (debug)
			{
			BIO_set_callback(benc,BIO_debug_callback);
			BIO_set_callback_arg(benc,(char *)bio_err);
			}

		if (printkey)
			{
			if (!nosalt)
				{
				printf("salt=");
				for (i=0; i<(int)sizeof(salt); i++)
					printf("%02X",salt[i]);
				printf("\n");
				}
			if (cipher->key_len > 0)
				{
				printf("key=");
				for (i=0; i<cipher->key_len; i++)
					printf("%02X",key[i]);
				printf("\n");
				}
			if (cipher->iv_len > 0)
				{
				printf("iv =");
				for (i=0; i<cipher->iv_len; i++)
					printf("%02X",iv[i]);
				printf("\n");
				}
			if (printkey == 2)
				{
				ret=0;
				goto end;
				}
			}
		}

	/* Only encrypt/decrypt as we write the file */
	if (benc != NULL)
		wbio=BIO_push(benc,wbio);

	for (;;)
		{
		inl=BIO_read(rbio,(char *)buff,bsize);
		if (inl <= 0) break;
		if (BIO_write(wbio,(char *)buff,inl) != inl)
			{
			BIO_printf(bio_err,"error writing output file\n");
			goto end;
			}
		}
	if (!BIO_flush(wbio))
		{
		BIO_printf(bio_err,"bad decrypt\n");
		goto end;
		}

	ret=0;
	if (verbose)
		{
		BIO_printf(bio_err,"bytes read   :%8ld\n",BIO_number_read(in));
		BIO_printf(bio_err,"bytes written:%8ld\n",BIO_number_written(out));
		}
end:
	ERR_print_errors(bio_err);
	if (strbuf != NULL) OPENSSL_free(strbuf);
	if (buff != NULL) OPENSSL_free(buff);
	if (in != NULL) BIO_free(in);
	if (out != NULL) BIO_free_all(out);
	if (benc != NULL) BIO_free(benc);
	if (b64 != NULL) BIO_free(b64);
	if(pass) OPENSSL_free(pass);
	apps_shutdown();
	OPENSSL_EXIT(ret);
	}
Пример #27
0
static OM_uint32
verify_mic_des
           (OM_uint32 * minor_status,
            const gsskrb5_ctx context_handle,
	    krb5_context context,
            const gss_buffer_t message_buffer,
            const gss_buffer_t token_buffer,
            gss_qop_t * qop_state,
	    krb5_keyblock *key,
	    const char *type
	    )
{
  u_char *p;
  EVP_MD_CTX *md5;
  u_char hash[16], *seq;
  DES_key_schedule schedule;
  EVP_CIPHER_CTX des_ctx;
  DES_cblock zero;
  DES_cblock deskey;
  uint32_t seq_number;
  OM_uint32 ret;
  int cmp;

  p = token_buffer->value;
  ret = _gsskrb5_verify_header (&p,
				   token_buffer->length,
				   type,
				   GSS_KRB5_MECHANISM);
  if (ret)
      return ret;

  if (memcmp(p, "\x00\x00", 2) != 0)
      return GSS_S_BAD_SIG;
  p += 2;
  if (memcmp (p, "\xff\xff\xff\xff", 4) != 0)
    return GSS_S_BAD_MIC;
  p += 4;
  p += 16;

  /* verify checksum */
  md5 = EVP_MD_CTX_create();
  EVP_DigestInit_ex(md5, EVP_md5(), NULL);
  EVP_DigestUpdate(md5, p - 24, 8);
  EVP_DigestUpdate(md5, message_buffer->value, message_buffer->length);
  EVP_DigestFinal_ex(md5, hash, NULL);
  EVP_MD_CTX_destroy(md5);

  memset (&zero, 0, sizeof(zero));
  memcpy (&deskey, key->keyvalue.data, sizeof(deskey));

  DES_set_key_unchecked (&deskey, &schedule);
  DES_cbc_cksum ((void *)hash, (void *)hash, sizeof(hash),
		 &schedule, &zero);
  if (ct_memcmp (p - 8, hash, 8) != 0) {
    memset (deskey, 0, sizeof(deskey));
    memset (&schedule, 0, sizeof(schedule));
    return GSS_S_BAD_MIC;
  }

  /* verify sequence number */

  HEIMDAL_MUTEX_lock(&context_handle->ctx_id_mutex);

  p -= 16;

  EVP_CIPHER_CTX_init(&des_ctx);
  EVP_CipherInit_ex(&des_ctx, EVP_des_cbc(), NULL, key->keyvalue.data, hash, 0);
  EVP_Cipher(&des_ctx, p, p, 8);
  EVP_CIPHER_CTX_cleanup(&des_ctx);

  memset (deskey, 0, sizeof(deskey));
  memset (&schedule, 0, sizeof(schedule));

  seq = p;
  _gsskrb5_decode_om_uint32(seq, &seq_number);

  if (context_handle->more_flags & LOCAL)
      cmp = ct_memcmp(&seq[4], "\xff\xff\xff\xff", 4);
  else
      cmp = ct_memcmp(&seq[4], "\x00\x00\x00\x00", 4);

  if (cmp != 0) {
    HEIMDAL_MUTEX_unlock(&context_handle->ctx_id_mutex);
    return GSS_S_BAD_MIC;
  }

  ret = _gssapi_msg_order_check(context_handle->order, seq_number);
  if (ret) {
      HEIMDAL_MUTEX_unlock(&context_handle->ctx_id_mutex);
      return ret;
  }

  HEIMDAL_MUTEX_unlock(&context_handle->ctx_id_mutex);

  return GSS_S_COMPLETE;
}
Пример #28
0
static int test_tls13_encryption(void)
{
    SSL_CTX *ctx = NULL;
    SSL *s = NULL;
    SSL3_RECORD rec;
    unsigned char *key = NULL, *iv = NULL, *seq = NULL;
    const EVP_CIPHER *ciph = EVP_aes_128_gcm();
    int ret = 0;
    size_t ivlen, ctr;

    /*
     * Encrypted TLSv1.3 records always have an outer content type of
     * application data, and a record version of TLSv1.2.
     */
    rec.data = NULL;
    rec.type = SSL3_RT_APPLICATION_DATA;
    rec.rec_version = TLS1_2_VERSION;

    ctx = SSL_CTX_new(TLS_method());
    if (!TEST_ptr(ctx)) {
        TEST_info("Failed creating SSL_CTX");
        goto err;
    }

    s = SSL_new(ctx);
    if (!TEST_ptr(s)) {
        TEST_info("Failed creating SSL");
        goto err;
    }

    s->enc_read_ctx = EVP_CIPHER_CTX_new();
    if (!TEST_ptr(s->enc_read_ctx))
        goto err;

    s->enc_write_ctx = EVP_CIPHER_CTX_new();
    if (!TEST_ptr(s->enc_write_ctx))
        goto err;

    s->s3->tmp.new_cipher = SSL_CIPHER_find(s, TLS13_AES_128_GCM_SHA256_BYTES);
    if (!TEST_ptr(s->s3->tmp.new_cipher)) {
        TEST_info("Failed to find cipher");
        goto err;
    }

    for (ctr = 0; ctr < OSSL_NELEM(refdata); ctr++) {
        /* Load the record */
        ivlen = EVP_CIPHER_iv_length(ciph);
        if (!load_record(&rec, &refdata[ctr], &key, s->read_iv, ivlen,
                         RECORD_LAYER_get_read_sequence(&s->rlayer))) {
            TEST_error("Failed loading key into EVP_CIPHER_CTX");
            goto err;
        }

        /* Set up the read/write sequences */
        memcpy(RECORD_LAYER_get_write_sequence(&s->rlayer),
               RECORD_LAYER_get_read_sequence(&s->rlayer), SEQ_NUM_SIZE);
        memcpy(s->write_iv, s->read_iv, ivlen);

        /* Load the key into the EVP_CIPHER_CTXs */
        if (EVP_CipherInit_ex(s->enc_write_ctx, ciph, NULL, key, NULL, 1) <= 0
                || EVP_CipherInit_ex(s->enc_read_ctx, ciph, NULL, key, NULL, 0)
                   <= 0) {
            TEST_error("Failed loading key into EVP_CIPHER_CTX\n");
            goto err;
        }

        /* Encrypt it */
        if (!TEST_size_t_eq(tls13_enc(s, &rec, 1, 1), 1)) {
            TEST_info("Failed to encrypt record %zu", ctr);
            goto err;
        }
        if (!TEST_true(test_record(&rec, &refdata[ctr], 1))) {
            TEST_info("Record %zu encryption test failed", ctr);
            goto err;
        }

        /* Decrypt it */
        if (!TEST_int_eq(tls13_enc(s, &rec, 1, 0), 1)) {
            TEST_info("Failed to decrypt record %zu", ctr);
            goto err;
        }
        if (!TEST_true(test_record(&rec, &refdata[ctr], 0))) {
            TEST_info("Record %zu decryption test failed", ctr);
            goto err;
        }

        OPENSSL_free(rec.data);
        OPENSSL_free(key);
        OPENSSL_free(iv);
        OPENSSL_free(seq);
        rec.data = NULL;
        key = NULL;
        iv = NULL;
        seq = NULL;
    }

    TEST_note("PASS: %zu records tested", ctr);
    ret = 1;

 err:
    OPENSSL_free(rec.data);
    OPENSSL_free(key);
    OPENSSL_free(iv);
    OPENSSL_free(seq);
    SSL_free(s);
    SSL_CTX_free(ctx);
    return ret;
}
Пример #29
0
int ssl3_change_cipher_state(SSL *s, int which)
{
    unsigned char *p, *mac_secret;
    unsigned char exp_key[EVP_MAX_KEY_LENGTH];
    unsigned char exp_iv[EVP_MAX_IV_LENGTH];
    unsigned char *ms, *key, *iv;
    EVP_CIPHER_CTX *dd;
    const EVP_CIPHER *c;
#ifndef OPENSSL_NO_COMP
    COMP_METHOD *comp;
#endif
    const EVP_MD *m;
    int n, i, j, k, cl;
    int reuse_dd = 0;

    c = s->s3->tmp.new_sym_enc;
    m = s->s3->tmp.new_hash;
    /* m == NULL will lead to a crash later */
    OPENSSL_assert(m);
#ifndef OPENSSL_NO_COMP
    if (s->s3->tmp.new_compression == NULL)
        comp = NULL;
    else
        comp = s->s3->tmp.new_compression->method;
#endif

    if (which & SSL3_CC_READ) {
        if (s->enc_read_ctx != NULL)
            reuse_dd = 1;
        else if ((s->enc_read_ctx = EVP_CIPHER_CTX_new()) == NULL)
            goto err;
        else
            /*
             * make sure it's initialised in case we exit later with an error
             */
            EVP_CIPHER_CTX_reset(s->enc_read_ctx);
        dd = s->enc_read_ctx;

        if (ssl_replace_hash(&s->read_hash, m) == NULL) {
                SSLerr(SSL_F_SSL3_CHANGE_CIPHER_STATE, ERR_R_INTERNAL_ERROR);
                goto err2;
        }
#ifndef OPENSSL_NO_COMP
        /* COMPRESS */
        COMP_CTX_free(s->expand);
        s->expand = NULL;
        if (comp != NULL) {
            s->expand = COMP_CTX_new(comp);
            if (s->expand == NULL) {
                SSLerr(SSL_F_SSL3_CHANGE_CIPHER_STATE,
                       SSL_R_COMPRESSION_LIBRARY_ERROR);
                goto err2;
            }
        }
#endif
        RECORD_LAYER_reset_read_sequence(&s->rlayer);
        mac_secret = &(s->s3->read_mac_secret[0]);
    } else {
        if (s->enc_write_ctx != NULL)
            reuse_dd = 1;
        else if ((s->enc_write_ctx = EVP_CIPHER_CTX_new()) == NULL)
            goto err;
        else
            /*
             * make sure it's initialised in case we exit later with an error
             */
            EVP_CIPHER_CTX_reset(s->enc_write_ctx);
        dd = s->enc_write_ctx;
        if (ssl_replace_hash(&s->write_hash, m) == NULL) {
                SSLerr(SSL_F_SSL3_CHANGE_CIPHER_STATE, ERR_R_INTERNAL_ERROR);
                goto err2;
        }
#ifndef OPENSSL_NO_COMP
        /* COMPRESS */
        COMP_CTX_free(s->compress);
        s->compress = NULL;
        if (comp != NULL) {
            s->compress = COMP_CTX_new(comp);
            if (s->compress == NULL) {
                SSLerr(SSL_F_SSL3_CHANGE_CIPHER_STATE,
                       SSL_R_COMPRESSION_LIBRARY_ERROR);
                goto err2;
            }
        }
#endif
        RECORD_LAYER_reset_write_sequence(&s->rlayer);
        mac_secret = &(s->s3->write_mac_secret[0]);
    }

    if (reuse_dd)
        EVP_CIPHER_CTX_reset(dd);

    p = s->s3->tmp.key_block;
    i = EVP_MD_size(m);
    if (i < 0)
        goto err2;
    cl = EVP_CIPHER_key_length(c);
    j = cl;
    k = EVP_CIPHER_iv_length(c);
    if ((which == SSL3_CHANGE_CIPHER_CLIENT_WRITE) ||
        (which == SSL3_CHANGE_CIPHER_SERVER_READ)) {
        ms = &(p[0]);
        n = i + i;
        key = &(p[n]);
        n += j + j;
        iv = &(p[n]);
        n += k + k;
    } else {
        n = i;
        ms = &(p[n]);
        n += i + j;
        key = &(p[n]);
        n += j + k;
        iv = &(p[n]);
        n += k;
    }

    if (n > s->s3->tmp.key_block_length) {
        SSLerr(SSL_F_SSL3_CHANGE_CIPHER_STATE, ERR_R_INTERNAL_ERROR);
        goto err2;
    }

    memcpy(mac_secret, ms, i);

    EVP_CipherInit_ex(dd, c, NULL, key, iv, (which & SSL3_CC_WRITE));

#ifdef OPENSSL_SSL_TRACE_CRYPTO
    if (s->msg_callback) {

        int wh = which & SSL3_CC_WRITE ?
            TLS1_RT_CRYPTO_WRITE : TLS1_RT_CRYPTO_READ;
        s->msg_callback(2, s->version, wh | TLS1_RT_CRYPTO_MAC,
                        mac_secret, EVP_MD_size(m), s, s->msg_callback_arg);
        if (c->key_len)
            s->msg_callback(2, s->version, wh | TLS1_RT_CRYPTO_KEY,
                            key, c->key_len, s, s->msg_callback_arg);
        if (k) {
            s->msg_callback(2, s->version, wh | TLS1_RT_CRYPTO_IV,
                            iv, k, s, s->msg_callback_arg);
        }
    }
#endif

    OPENSSL_cleanse(exp_key, sizeof(exp_key));
    OPENSSL_cleanse(exp_iv, sizeof(exp_iv));
    return (1);
 err:
    SSLerr(SSL_F_SSL3_CHANGE_CIPHER_STATE, ERR_R_MALLOC_FAILURE);
 err2:
    OPENSSL_cleanse(exp_key, sizeof(exp_key));
    OPENSSL_cleanse(exp_iv, sizeof(exp_iv));
    return (0);
}
Пример #30
0
int AesFileEnc::do_crypt(FILE *in, FILE *out, int do_encrypt)
{
	/* Allow enough space in output buffer for additional block */
	unsigned char inbuf[1024], outbuf[1024 + EVP_MAX_BLOCK_LENGTH];
	int inlen, outlen;
	EVP_CIPHER_CTX ctx;

	std::cout << "tutaj";
	unsigned char* key = this->key();
	//	std::cout <<key<<std::endl;
	//unsigned char key[] = "0123456789abcdeF";
	std::cout <<key<< std::endl;


	//unsigned char iv[] = "1234567887654321";
	EVP_CIPHER_CTX_init(&ctx);
	
	switch(this->type)
	{
		case cbc128:
			EVP_CipherInit_ex(&ctx, EVP_aes_128_cbc(), NULL, NULL, NULL,
				do_encrypt);
			break;
		case cbc192:
			EVP_CipherInit_ex(&ctx, EVP_aes_192_cbc(), NULL, NULL, NULL,
				do_encrypt);
		break;
		case cbc256:
			EVP_CipherInit_ex(&ctx, EVP_aes_256_cbc(), NULL, NULL, NULL,
				do_encrypt);
			break;
		case ecb128:
			EVP_CipherInit_ex(&ctx, EVP_aes_128_ecb(), NULL, NULL, NULL,
				do_encrypt);
			break;
		case ecb192:
			EVP_CipherInit_ex(&ctx, EVP_aes_192_ecb(), NULL, NULL, NULL,
				do_encrypt);
			break;
		case ecb256:
			EVP_CipherInit_ex(&ctx, EVP_aes_256_ecb(), NULL, NULL, NULL,
				do_encrypt);
			break;
		case cfb128:
			EVP_CipherInit_ex(&ctx, EVP_aes_128_cfb(), NULL, NULL, NULL,
				do_encrypt);
			break;
		case cfb192:
			EVP_CipherInit_ex(&ctx, EVP_aes_192_cfb(), NULL, NULL, NULL,
				do_encrypt);
			break;
		case cfb256:
			EVP_CipherInit_ex(&ctx, EVP_aes_256_cfb(), NULL, NULL, NULL,
				do_encrypt);
			break;
		case ofb128:
			EVP_CipherInit_ex(&ctx, EVP_aes_128_ofb(), NULL, NULL, NULL,
				do_encrypt);

			break;
		case ofb192:
			EVP_CipherInit_ex(&ctx, EVP_aes_192_ofb(), NULL, NULL, NULL,
				do_encrypt);
			break;
		case ofb256:
			EVP_CipherInit_ex(&ctx, EVP_aes_256_ofb(), NULL, NULL, NULL,
				do_encrypt);
			break;
	}
	unsigned char *iv = this->iv(EVP_CIPHER_CTX_iv_length(&ctx));	
			std::cout<< this->keyLength << std::endl;
			std::cout<< EVP_CIPHER_CTX_iv_length(&ctx) <<std::endl;
			OPENSSL_assert(EVP_CIPHER_CTX_key_length(&ctx) == this->keyLength);
			//OPENSSL_assert(EVP_CIPHER_CTX_iv_length(&ctx) == this->keyLength);
			EVP_CipherInit_ex(&ctx, NULL, NULL, key, iv, do_encrypt);
	
			for(;;)
					{
					inlen = fread(inbuf, 1, 1024, in);
					if(inlen <= 0) break;
					if(!EVP_CipherUpdate(&ctx, outbuf, &outlen, inbuf, inlen))
							{
	
							EVP_CIPHER_CTX_cleanup(&ctx);
							return 0;
							}
					fwrite(outbuf, 1, outlen, out);
					}
			if(!EVP_CipherFinal_ex(&ctx, outbuf, &outlen))
					{

					EVP_CIPHER_CTX_cleanup(&ctx);
					return 0;
					}
			fwrite(outbuf, 1, outlen, out);

			EVP_CIPHER_CTX_cleanup(&ctx);
			return 1;
			}