⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 ismacryp.c

📁 一个用于智能手机的多媒体库适合S60 WinCE的跨平台开发库
💻 C
📖 第 1 页 / 共 2 页
字号:
	}		nb_tracks = gf_isom_get_track_count(mp4);	cur_tk = 1;	e = GF_OK;	for (i=0; i<nb_tracks; i++) {		u32 trackID = gf_isom_get_track_id(mp4, i+1);		scheme_type = gf_isom_is_media_encrypted(mp4, i+1, 1);		if (!scheme_type) continue;		for (idx=0; idx<count; idx++) {			a_tci = (GF_TrackCryptInfo *)gf_list_get(info->tcis, idx);			if (a_tci->trackID == trackID) break;		}		if (idx==count) {			if (!drm_file || info->has_common_key) idx = common_idx;			/*no available KMS info for this track*/			else continue;		}		if (count) {			a_tci = (GF_TrackCryptInfo *)gf_list_get(info->tcis, idx);			memcpy(&tci, a_tci, sizeof(GF_TrackCryptInfo));		} else {			memset(&tci, 0, sizeof(GF_TrackCryptInfo));			tci.trackID = trackID;		}		if (gf_isom_is_ismacryp_media(mp4, i+1, 1)) {			e = gf_isom_get_ismacryp_info(mp4, i+1, 1, NULL, &scheme_type, NULL, &scheme_URI, &KMS_URI, NULL, NULL, NULL);		} else if (gf_isom_is_omadrm_media(mp4, i+1, 1)) {			if (!drm_file) {				GF_LOG(GF_LOG_ERROR, GF_LOG_AUTHOR, ("[ISMA E&A] Cannot decrypt OMA (P)DCF file without GPAC's DRM file & keys\n"));				continue;			}			KMS_URI = "OMA DRM";		} else {			GF_LOG(GF_LOG_WARNING, GF_LOG_AUTHOR, ("[ISMA E&A] TrackID %d encrypted with unknown scheme %s - skipping\n", trackID, gf_4cc_to_str(scheme_type) ));			continue;		}		/*get key and salt from KMS*/		/*GPAC*/		if (!strnicmp(KMS_URI, "(key)", 5)) {			char data[100];			gf_base64_decode((char*)KMS_URI+5, strlen(KMS_URI)-5, data, 100);			memcpy(tci.key, data, sizeof(char)*16);			memcpy(tci.salt, data+16, sizeof(char)*8);		}		/*MPEG4IP*/		else if (!stricmp(KMS_URI, "AudioKey") || !stricmp(KMS_URI, "VideoKey")) {			if (!gf_ismacryp_mpeg4ip_get_info((char *) KMS_URI, tci.key, tci.salt)) {				GF_LOG(GF_LOG_ERROR, GF_LOG_AUTHOR, ("[ISMA E&A] Couldn't load MPEG4IP ISMACryp keys for TrackID %d\n", trackID));				continue;			}		} else if (!drm_file) {			FILE *test = NULL;			if (!stricmp(scheme_URI, "urn:gpac:isma:encryption_scheme")) test = fopen(KMS_URI, "rt");			if (!test) {				GF_LOG(GF_LOG_INFO, GF_LOG_AUTHOR, ("[ISMA E&A] TrackID %d does not contain decryption keys - skipping\n", trackID));				continue;			}			fclose(test);			if (gf_ismacryp_gpac_get_info(tci.trackID, (char *) KMS_URI, tci.key, tci.salt) != GF_OK) {				GF_LOG(GF_LOG_ERROR, GF_LOG_AUTHOR, ("[ISMA E&A] Couldn't load TrackID %d keys in GPAC DRM file %s\n", tci.trackID, KMS_URI));				continue;			}		}		if (KMS_URI && strlen(tci.KMS_URI) && strcmp(KMS_URI, tci.KMS_URI) )			GF_LOG(GF_LOG_WARNING, GF_LOG_AUTHOR, ("[ISMA E&A] KMS URI for trackID %d Mismatch\n", trackID));		if (drm_file || (KMS_URI && strncmp(KMS_URI, "(key)", 5)) ) {			strcpy(tci.KMS_URI, KMS_URI ? KMS_URI : "");		} else {			strcpy(tci.KMS_URI, "self-contained");		}		e = gf_ismacryp_decrypt_track(mp4, &tci, NULL, NULL);		if (e) break;	}	if (info) del_crypt_info(info);	return e;}GF_EXPORTGF_Err gf_ismacryp_encrypt_track(GF_ISOFile *mp4, GF_TrackCryptInfo *tci, void (*progress)(void *cbk, u32 done, u32 total), void *cbk){	char IV[16];	GF_ISOSample *samp;	GF_ISMASample *isamp;	GF_Crypt *mc;	u32 i, count, di, track, IV_size, rand, avc_size_length;	u64 BSO;	GF_ESD *esd;	GF_IPMPPtr *ipmpdp;	GF_IPMP_Descriptor *ipmpd;	GF_IPMPUpdate *ipmpdU;	GF_IPMPX_ISMACryp *ismac;	GF_Err e;	Bool prev_sample_encryped, has_crypted_samp;	avc_size_length = 0;	track = gf_isom_get_track_by_id(mp4, tci->trackID);	if (!track) {		GF_LOG(GF_LOG_ERROR, GF_LOG_AUTHOR, ("[ISMA E&A] Cannot find TrackID %d in input file - skipping\n", tci->trackID));		return GF_OK;	}	esd = gf_isom_get_esd(mp4, track, 1);	if (esd && (esd->decoderConfig->streamType==GF_STREAM_OD)) {		gf_odf_desc_del((GF_Descriptor *) esd);		GF_LOG(GF_LOG_ERROR, GF_LOG_AUTHOR, ("[ISMA E&A] Cannot encrypt OD tracks - skipping"));		return GF_NOT_SUPPORTED;	}	if (esd) {		if (esd->decoderConfig->objectTypeIndication==0x21) avc_size_length = 1;		gf_odf_desc_del((GF_Descriptor*) esd);	}	if (avc_size_length) {		GF_AVCConfig *avccfg = gf_isom_avc_config_get(mp4, track, 1);		avc_size_length = avccfg->nal_unit_size;		gf_odf_avc_cfg_del(avccfg);		if (avc_size_length != 4) {			GF_LOG(GF_LOG_ERROR, GF_LOG_AUTHOR, ("[ISMA E&A] Cannot encrypt AVC/H264 track with %d size_length field - onmy 4 supported\n", avc_size_length));			return GF_NOT_SUPPORTED;		}	}	if (!tci->enc_type && !strlen(tci->Scheme_URI)) strcpy(tci->Scheme_URI, "urn:gpac:isma:encryption_scheme");	if (!gf_isom_has_sync_points(mp4, track) &&	((tci->sel_enc_type==GF_ISMACRYP_SELENC_RAP) || (tci->sel_enc_type==GF_ISMACRYP_SELENC_NON_RAP)) ) {		GF_LOG(GF_LOG_WARNING, GF_LOG_AUTHOR, ("[ISMA E&A] All samples in trackID %d are random access - disabling selective encryption\n", tci->trackID));		tci->sel_enc_type = GF_ISMACRYP_SELENC_NONE;	}	else if ((tci->sel_enc_type==GF_ISMACRYP_SELENC_RAND) || (tci->sel_enc_type==GF_ISMACRYP_SELENC_RAND_RANGE)) {		gf_rand_init(1);	}	BSO = gf_isom_get_media_data_size(mp4, track);	if (tci->enc_type==0) {		if (BSO<0xFFFF) IV_size = 2;		else if (BSO<0xFFFFFFFF) IV_size = 4;		else IV_size = 8;	} else {		/*128 bit IV in OMA*/		IV_size = 16;	}	GF_LOG(GF_LOG_INFO, GF_LOG_AUTHOR, ("[ISMA E&A] Encrypting track ID %d - KMS: %s%s\n", tci->trackID, tci->KMS_URI, tci->sel_enc_type ? " - Selective Encryption" : ""));	/*init crypto*/	memset(IV, 0, sizeof(char)*16);	memcpy(IV, tci->salt, sizeof(char)*8);	mc = gf_crypt_open("AES-128", "CTR");	if (!mc) {		GF_LOG(GF_LOG_ERROR, GF_LOG_AUTHOR, ("[ISMA E&A] Cannot open AES-128 CTR\n"));		return GF_IO_ERR;	}	e = gf_crypt_init(mc, tci->key, 16, IV);	if (e) {		GF_LOG(GF_LOG_ERROR, GF_LOG_AUTHOR, ("[ISMA E&A] Cannot initialize AES-128 CTR (%s)\n", gf_error_to_string(e)) );		gf_crypt_close(mc);		return GF_IO_ERR;	}	if (!stricmp(tci->KMS_URI, "self")) {		char Data[100], d64[100];		u32 s64;		memcpy(Data, tci->key, sizeof(char)*16);		memcpy(Data+16, tci->salt, sizeof(char)*8);		s64 = gf_base64_encode(Data, 24, d64, 100);		d64[s64] = 0;		strcpy(tci->KMS_URI, "(key)");		strcat(tci->KMS_URI, d64);	}	/*create ISMA protection*/	if (tci->enc_type==0) {		e = gf_isom_set_ismacryp_protection(mp4, track, 1, GF_ISOM_ISMACRYP_SCHEME, 1, 			tci->Scheme_URI, tci->KMS_URI, (tci->sel_enc_type!=0) ? 1 : 0, 0, IV_size);	 	} else {		e = gf_isom_set_oma_protection(mp4, track, 1, 			strlen(tci->Scheme_URI) ? tci->Scheme_URI : NULL,			tci->KMS_URI, 			tci->encryption, BSO, 			tci->TextualHeadersLen ? tci->TextualHeaders : NULL, 			tci->TextualHeadersLen,			(tci->sel_enc_type!=0) ? 1 : 0, 0, IV_size);	}	if (e) return e;	has_crypted_samp = 0;	BSO = 0;	prev_sample_encryped = 1;	if (gf_isom_has_time_offset(mp4, track)) gf_isom_set_cts_packing(mp4, track, 1);	count = gf_isom_get_sample_count(mp4, track);	for (i = 0; i < count; i++) {		samp = gf_isom_get_sample(mp4, track, i+1, &di); 		isamp = gf_isom_ismacryp_new_sample();		isamp->IV_length = IV_size;		isamp->KI_length = 0;		switch (tci->sel_enc_type) {		case GF_ISMACRYP_SELENC_RAP:			if (samp->IsRAP) isamp->flags |= GF_ISOM_ISMA_IS_ENCRYPTED;			break;		case GF_ISMACRYP_SELENC_NON_RAP:			if (!samp->IsRAP) isamp->flags |= GF_ISOM_ISMA_IS_ENCRYPTED;			break;		/*random*/		case GF_ISMACRYP_SELENC_RAND:			rand = gf_rand();			if (rand%2) isamp->flags |= GF_ISOM_ISMA_IS_ENCRYPTED;			break;		/*random every sel_freq samples*/		case GF_ISMACRYP_SELENC_RAND_RANGE:			if (!(i%tci->sel_enc_range)) has_crypted_samp = 0;			if (!has_crypted_samp) {				rand = gf_rand();				if (!(rand%tci->sel_enc_range)) isamp->flags |= GF_ISOM_ISMA_IS_ENCRYPTED;				if (!(isamp->flags & GF_ISOM_ISMA_IS_ENCRYPTED) && !( (1+i)%tci->sel_enc_range)) {					isamp->flags |= GF_ISOM_ISMA_IS_ENCRYPTED;				}				has_crypted_samp = (isamp->flags & GF_ISOM_ISMA_IS_ENCRYPTED);			}			break;		/*every sel_freq samples*/		case GF_ISMACRYP_SELENC_RANGE:			if (!(i%tci->sel_enc_type)) isamp->flags |= GF_ISOM_ISMA_IS_ENCRYPTED;			break;		case 0:			isamp->flags |= GF_ISOM_ISMA_IS_ENCRYPTED;			break;		default:			break;		}		if (tci->sel_enc_type) isamp->flags |= GF_ISOM_ISMA_USE_SEL_ENC;		/*isma e&a stores AVC1 in AVC/H264 annex B bitstream fashion, with 0x00000001 start codes*/		if (avc_size_length) {			u32 done = 0;			u8 *d = samp->data;			while (done < samp->dataLength) {				u32 nal_size = GF_4CC(d[0], d[1], d[2], d[3]);				d[0] = d[1] = d[2] = 0; d[3] = 1;				d += 4 + nal_size;				done += 4 + nal_size;			}		}		if (isamp->flags & GF_ISOM_ISMA_IS_ENCRYPTED) {			/*resync IV*/			if (!prev_sample_encryped) resync_IV(mc, BSO, tci->salt);			gf_crypt_encrypt(mc, samp->data, samp->dataLength);			prev_sample_encryped = 1;		} else {			prev_sample_encryped = 0;		}		isamp->IV = BSO;		BSO += samp->dataLength;		isamp->data = samp->data;		isamp->dataLength = samp->dataLength;		samp->data = NULL;		samp->dataLength = 0;		gf_isom_ismacryp_sample_to_sample(isamp, samp);		gf_isom_ismacryp_delete_sample(isamp);		gf_isom_update_sample(mp4, track, i+1, samp, 1);		gf_isom_sample_del(&samp);		gf_set_progress("ISMA Encrypt", i+1, count);	}	gf_isom_set_cts_packing(mp4, track, 0);	gf_crypt_close(mc);	/*format as IPMP(X) - note that the ISMACryp spec is broken since it always uses IPMPPointers to a 	single desc which would assume the same protection (eg key & salt) for all streams using it...*/	if (!tci->ipmp_type) return GF_OK;	ipmpdp = (GF_IPMPPtr*)gf_odf_desc_new(GF_ODF_IPMP_PTR_TAG);	if (!tci->ipmp_desc_id) tci->ipmp_desc_id = track;	if (tci->ipmp_type==2) {		ipmpdp->IPMP_DescriptorID = 0xFF;		ipmpdp->IPMP_DescriptorIDEx = tci->ipmp_desc_id;	} else {		ipmpdp->IPMP_DescriptorID = tci->ipmp_desc_id;	}	gf_isom_add_desc_to_description(mp4, track, 1, (GF_Descriptor *)ipmpdp);	gf_odf_desc_del((GF_Descriptor*)ipmpdp);	ipmpdU = (GF_IPMPUpdate*)gf_odf_com_new(GF_ODF_IPMP_UPDATE_TAG);	/*format IPMPD*/	ipmpd = (GF_IPMP_Descriptor*)gf_odf_desc_new(GF_ODF_IPMP_TAG);	if (tci->ipmp_type==2) {		ipmpd->IPMP_DescriptorID = 0xFF;		ipmpd->IPMP_DescriptorIDEx = tci->ipmp_desc_id;		ipmpd->IPMPS_Type = 0xFFFF;		ipmpd->IPMP_ToolID[14] = 0x49; ipmpd->IPMP_ToolID[15] = 0x53;		ipmpd->control_point = 1;		ipmpd->cp_sequence_code = 0x80;		/*format IPMPXData*/		ismac = (GF_IPMPX_ISMACryp *) gf_ipmpx_data_new(GF_IPMPX_ISMACRYP_TAG);		ismac->cryptoSuite = 1;	/*default ISMA AESCTR128*/		ismac->IV_length = IV_size;		ismac->key_indicator_length = 0;		ismac->use_selective_encryption = (tci->sel_enc_type!=0)? 1 : 0;		gf_list_add(ipmpd->ipmpx_data, ismac);	} else {		ipmpd->IPMP_DescriptorID = tci->ipmp_desc_id;	}	gf_list_add(ipmpdU->IPMPDescList, ipmpd);	for (i=0; i<gf_isom_get_track_count(mp4); i++) {		GF_ODCodec *cod;		if (gf_isom_get_media_type(mp4, i+1) != GF_ISOM_MEDIA_OD) continue;		/*add com*/		samp = gf_isom_get_sample(mp4, i+1, 1, &di);		cod = gf_odf_codec_new();		gf_odf_codec_set_au(cod, samp->data, samp->dataLength);		gf_odf_codec_decode(cod);		gf_odf_codec_add_com(cod, (GF_ODCom *) ipmpdU);		free(samp->data);		samp->data = NULL;		samp->dataLength = 0;		gf_odf_codec_encode(cod, 1);		gf_odf_codec_get_au(cod, &samp->data, &samp->dataLength);		ipmpdU = NULL;		gf_odf_codec_del(cod);		gf_isom_update_sample(mp4, i+1, 1, samp, 1);		gf_isom_sample_del(&samp);		if (tci->ipmp_type==2) {			GF_IPMP_ToolList*ipmptl = (GF_IPMP_ToolList*)gf_odf_desc_new(GF_ODF_IPMP_TL_TAG);			GF_IPMP_Tool *ipmpt = (GF_IPMP_Tool*)gf_odf_desc_new(GF_ODF_IPMP_TOOL_TAG);			gf_list_add(ipmptl->ipmp_tools, ipmpt);			ipmpt->IPMP_ToolID[14] = 0x49; ipmpt->IPMP_ToolID[15] = 0x53;			gf_isom_add_desc_to_root_od(mp4, (GF_Descriptor *)ipmptl);			gf_odf_desc_del((GF_Descriptor *)ipmptl);		}		break;	}	return e;}GF_EXPORTGF_Err gf_ismacryp_crypt_file(GF_ISOFile *mp4, const char *drm_file){	GF_Err e;	u32 i, count, nb_tracks, common_idx, idx;	ISMACrypInfo *info;	GF_TrackCryptInfo *tci;	info = load_crypt_file(drm_file);	if (!info) {		GF_LOG(GF_LOG_ERROR, GF_LOG_AUTHOR, ("[ISMA E&A] Cannot open or validate xml file %s\n", drm_file));		return GF_NOT_SUPPORTED;	}	e = GF_OK;	count = gf_list_count(info->tcis);	common_idx=0;	if (info && info->has_common_key) {		for (common_idx=0; common_idx<count; common_idx++) {			tci = (GF_TrackCryptInfo *)gf_list_get(info->tcis, common_idx);			if (!tci->trackID) break;		}	}	nb_tracks = gf_isom_get_track_count(mp4);	for (i=0; i<nb_tracks; i++) {		u32 trackID = gf_isom_get_track_id(mp4, i+1);		for (idx=0; idx<count; idx++) {			tci = (GF_TrackCryptInfo *)gf_list_get(info->tcis, idx);			if (tci->trackID==trackID) break;		}		if (idx==count) {			if (!info->has_common_key) continue;			idx = common_idx;		}		tci = (GF_TrackCryptInfo *)gf_list_get(info->tcis, idx);		/*default to FILE uri*/		if (!strlen(tci->KMS_URI)) strcpy(tci->KMS_URI, drm_file);		e = gf_ismacryp_encrypt_track(mp4, tci, NULL, NULL);		if (e) break;	}	del_crypt_info(info);	return e;}#endifGF_EXPORTGF_Err gf_media_get_file_hash(const char *file, u8 hash[20]) {	u8 block[1024];	u32 read;	u64 size, tot;	FILE *in;	GF_BitStream *bs = NULL;	GF_SHA1Context ctx;	Bool is_isom = gf_isom_probe_file(file);	in = fopen(file, "rb");	gf_f64_seek(in, 0, SEEK_END);	size = gf_f64_tell(in);	gf_f64_seek(in, 0, SEEK_SET);	gf_sha1_starts(&ctx);	tot = 0;	if (is_isom) bs = gf_bs_from_file(in, GF_BITSTREAM_READ);	while (tot<size) {		if (is_isom) {			u64 box_size = gf_bs_peek_bits(bs, 32, 0);			u32 box_type = gf_bs_peek_bits(bs, 32, 4);			/*till end of file*/			if (!box_size) box_size = size-tot;			/*64-bit size*/			else if (box_size==1) box_size = gf_bs_peek_bits(bs, 64, 8);			/*skip all MutableDRMInformation*/			if (box_type==GF_4CC('m','d','r','i')) {				gf_bs_skip_bytes(bs, box_size);				tot += box_size;			} else {				u32 bsize = 0;				while (bsize<box_size) {					u32 to_read = (u32) ((box_size-bsize<1024) ? (box_size-bsize) : 1024);					gf_bs_read_data(bs, block, to_read);					gf_sha1_update(&ctx, block, to_read);					bsize += to_read;				}				tot += box_size;			}		} else {			read = fread(block, 1, 1024, in);			gf_sha1_update(&ctx, block, read);			tot += read;		}	}	gf_sha1_finish(&ctx, hash);	if (bs) gf_bs_del(bs);	fclose(in);	return GF_OK;}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -