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

📄 cms.c

📁 samba最新软件
💻 C
📖 第 1 页 / 共 3 页
字号:
	ret = hx509_crypto_set_key_data(crypto, key.data, key.length);	if (ret) {	    hx509_crypto_destroy(crypto);	    hx509_set_error_string(context, 0, ret,				   "Failed to set key for decryption "				   "of EnvelopedData");	    goto out;	}		ret = hx509_crypto_decrypt(crypto,				   enccontent->data,				   enccontent->length,				   ivec.length ? &ivec : NULL,				   content);	hx509_crypto_destroy(crypto);	if (ret) {	    hx509_set_error_string(context, 0, ret,				   "Failed to decrypt EnvelopedData");	    goto out;	}    }out:    free_EnvelopedData(&ed);    der_free_octet_string(&key);    if (ivec.length)	der_free_octet_string(&ivec);    if (ret) {	der_free_oid(contentType);	der_free_octet_string(content);    }    return ret;}/** * Encrypt end encode EnvelopedData. * * Encrypt and encode EnvelopedData. The data is encrypted with a * random key and the the random key is encrypted with the * certificates private key. This limits what private key type can be * used to RSA. * * @param context A hx509 context. * @param flags flags to control the behavior, no flags today * @param cert Certificate to encrypt the EnvelopedData encryption key * with. * @param data pointer the data to encrypt. * @param length length of the data that data point to. * @param encryption_type Encryption cipher to use for the bulk data, * use NULL to get default. * @param contentType type of the data that is encrypted * @param content the output of the function, * free with der_free_octet_string(). * * @ingroup hx509_cms */inthx509_cms_envelope_1(hx509_context context,		     int flags,		     hx509_cert cert,		     const void *data,		     size_t length,		     const heim_oid *encryption_type,		     const heim_oid *contentType,		     heim_octet_string *content){    KeyTransRecipientInfo *ri;    heim_octet_string ivec;    heim_octet_string key;    hx509_crypto crypto = NULL;    EnvelopedData ed;    size_t size;    int ret;    memset(&ivec, 0, sizeof(ivec));    memset(&key, 0, sizeof(key));    memset(&ed, 0, sizeof(ed));    memset(content, 0, sizeof(*content));    if (encryption_type == NULL)	encryption_type = oid_id_aes_256_cbc();    ret = _hx509_check_key_usage(context, cert, 1 << 2, TRUE);    if (ret)	goto out;    ret = hx509_crypto_init(context, NULL, encryption_type, &crypto);    if (ret)	goto out;    ret = hx509_crypto_set_random_key(crypto, &key);    if (ret) {	hx509_set_error_string(context, 0, ret,			       "Create random key for EnvelopedData content");	goto out;    }    ret = hx509_crypto_random_iv(crypto, &ivec);    if (ret) {	hx509_set_error_string(context, 0, ret,			       "Failed to create a random iv");	goto out;    }    ret = hx509_crypto_encrypt(crypto,			       data,			       length,			       &ivec,			       &ed.encryptedContentInfo.encryptedContent);    if (ret) {	hx509_set_error_string(context, 0, ret,			       "Failed to encrypt EnvelopedData content");	goto out;    }    {	AlgorithmIdentifier *enc_alg;	enc_alg = &ed.encryptedContentInfo.contentEncryptionAlgorithm;	ret = der_copy_oid(encryption_type, &enc_alg->algorithm);	if (ret) {	    hx509_set_error_string(context, 0, ret,				   "Failed to set crypto oid "				   "for EnvelopedData");	    goto out;	}		ALLOC(enc_alg->parameters, 1);	if (enc_alg->parameters == NULL) {	    ret = ENOMEM;	    hx509_set_error_string(context, 0, ret,				   "Failed to allocate crypto paramaters "				   "for EnvelopedData");	    goto out;	}	ret = hx509_crypto_get_params(context,				      crypto,				      &ivec,				      enc_alg->parameters);	if (ret) {	    goto out;	}    }    ALLOC_SEQ(&ed.recipientInfos, 1);    if (ed.recipientInfos.val == NULL) {	ret = ENOMEM;	hx509_set_error_string(context, 0, ret,			       "Failed to allocate recipients info "			       "for EnvelopedData");	goto out;    }    ri = &ed.recipientInfos.val[0];    ri->version = 0;    ret = fill_CMSIdentifier(cert, CMS_ID_SKI, &ri->rid);    if (ret) {	hx509_set_error_string(context, 0, ret,			       "Failed to set CMS identifier info "			       "for EnvelopedData");	goto out;    }    ret = _hx509_cert_public_encrypt(context,				     &key, cert,				     &ri->keyEncryptionAlgorithm.algorithm,				     &ri->encryptedKey);    if (ret) {	hx509_set_error_string(context, HX509_ERROR_APPEND, ret,			       "Failed to encrypt transport key for "			       "EnvelopedData");	goto out;    }    /*     *     */    ed.version = 0;    ed.originatorInfo = NULL;    ret = der_copy_oid(contentType, &ed.encryptedContentInfo.contentType);    if (ret) {	hx509_set_error_string(context, 0, ret,			       "Failed to copy content oid for "			       "EnvelopedData");	goto out;    }    ed.unprotectedAttrs = NULL;    ASN1_MALLOC_ENCODE(EnvelopedData, content->data, content->length,		       &ed, &size, ret);    if (ret) {	hx509_set_error_string(context, 0, ret,			       "Failed to encode EnvelopedData");	goto out;    }    if (size != content->length)	_hx509_abort("internal ASN.1 encoder error");out:    if (crypto)	hx509_crypto_destroy(crypto);    if (ret)	der_free_octet_string(content);    der_free_octet_string(&key);    der_free_octet_string(&ivec);    free_EnvelopedData(&ed);    return ret;}static intany_to_certs(hx509_context context, const SignedData *sd, hx509_certs certs){    int ret, i;    if (sd->certificates == NULL)	return 0;    for (i = 0; i < sd->certificates->len; i++) {	hx509_cert c;	ret = hx509_cert_init_data(context, 				   sd->certificates->val[i].data, 				   sd->certificates->val[i].length,				   &c);	if (ret)	    return ret;	ret = hx509_certs_add(context, certs, c);	hx509_cert_free(c);	if (ret)	    return ret;    }    return 0;}static const Attribute *find_attribute(const CMSAttributes *attr, const heim_oid *oid){    int i;    for (i = 0; i < attr->len; i++)	if (der_heim_oid_cmp(&attr->val[i].type, oid) == 0)	    return &attr->val[i];    return NULL;}/** * Decode SignedData and verify that the signature is correct. * * @param context A hx509 context. * @param ctx a hx509 version context * @param data * @param length length of the data that data point to. * @param signedContent * @param pool certificate pool to build certificates paths. * @param contentType free with der_free_oid() * @param content the output of the function, free with * der_free_octet_string(). * @param signer_certs list of the cerficates used to sign this * request, free with hx509_certs_free(). * * @ingroup hx509_cms */inthx509_cms_verify_signed(hx509_context context,			hx509_verify_ctx ctx,			const void *data,			size_t length,			const heim_octet_string *signedContent,			hx509_certs pool,			heim_oid *contentType,			heim_octet_string *content,			hx509_certs *signer_certs){    SignerInfo *signer_info;    hx509_cert cert = NULL;    hx509_certs certs = NULL;    SignedData sd;    size_t size;    int ret, i, found_valid_sig;    *signer_certs = NULL;    content->data = NULL;    content->length = 0;    contentType->length = 0;    contentType->components = NULL;    memset(&sd, 0, sizeof(sd));    ret = decode_SignedData(data, length, &sd, &size);    if (ret) {	hx509_set_error_string(context, 0, ret,			       "Failed to decode SignedData");	goto out;    }    if (sd.encapContentInfo.eContent == NULL && signedContent == NULL) {	ret = HX509_CMS_NO_DATA_AVAILABLE;	hx509_set_error_string(context, 0, ret,			       "No content data in SignedData");	goto out;    }    if (sd.encapContentInfo.eContent && signedContent) {	ret = HX509_CMS_NO_DATA_AVAILABLE;	hx509_set_error_string(context, 0, ret,			       "Both external and internal SignedData");	goto out;    }    if (sd.encapContentInfo.eContent)	signedContent = sd.encapContentInfo.eContent;    ret = hx509_certs_init(context, "MEMORY:cms-cert-buffer",			   0, NULL, &certs);    if (ret)	goto out;    ret = hx509_certs_init(context, "MEMORY:cms-signer-certs",			   0, NULL, signer_certs);    if (ret)	goto out;    /* XXX Check CMS version */    ret = any_to_certs(context, &sd, certs);    if (ret)	goto out;    if (pool) {	ret = hx509_certs_merge(context, certs, pool);	if (ret)	    goto out;    }    for (found_valid_sig = 0, i = 0; i < sd.signerInfos.len; i++) {	heim_octet_string *signed_data;	const heim_oid *match_oid;	heim_oid decode_oid;	signer_info = &sd.signerInfos.val[i];	match_oid = NULL;	if (signer_info->signature.length == 0) {	    ret = HX509_CMS_MISSING_SIGNER_DATA;	    hx509_set_error_string(context, 0, ret,				   "SignerInfo %d in SignedData "				   "missing sigature", i);	    continue;	}	ret = find_CMSIdentifier(context, &signer_info->sid, certs, &cert,				 HX509_QUERY_KU_DIGITALSIGNATURE);	if (ret)	    continue;	if (signer_info->signedAttrs) {	    const Attribute *attr;		    CMSAttributes sa;	    heim_octet_string os;	    sa.val = signer_info->signedAttrs->val;	    sa.len = signer_info->signedAttrs->len;	    /* verify that sigature exists */	    attr = find_attribute(&sa, oid_id_pkcs9_messageDigest());	    if (attr == NULL) {		ret = HX509_CRYPTO_SIGNATURE_MISSING;		hx509_set_error_string(context, 0, ret,				       "SignerInfo have signed attributes "				       "but messageDigest (signature) "				       "is missing");		goto next_sigature;	    }	    if (attr->value.len != 1) {		ret = HX509_CRYPTO_SIGNATURE_MISSING;		hx509_set_error_string(context, 0, ret,				       "SignerInfo have more then one "				       "messageDigest (signature)");		goto next_sigature;	    }		    ret = decode_MessageDigest(attr->value.val[0].data,				       attr->value.val[0].length,				       &os,				       &size);	    if (ret) {		hx509_set_error_string(context, 0, ret,				       "Failed to decode "				       "messageDigest (signature)");		goto next_sigature;	    }	    ret = _hx509_verify_signature(context,					  NULL,					  &signer_info->digestAlgorithm,					  signedContent,					  &os);	    der_free_octet_string(&os);	    if (ret) {		hx509_set_error_string(context, HX509_ERROR_APPEND, ret,				       "Failed to verify messageDigest");		goto next_sigature;	    }	    /*	     * Fetch content oid inside signedAttrs or set it to	     * id-pkcs7-data.	     */	    attr = find_attribute(&sa, oid_id_pkcs9_contentType());	    if (attr == NULL) {		match_oid = oid_id_pkcs7_data();	    } else {		if (attr->value.len != 1) {		    ret = HX509_CMS_DATA_OID_MISMATCH;		    hx509_set_error_string(context, 0, ret,					   "More then one oid in signedAttrs");		    goto next_sigature;		}		ret = decode_ContentType(attr->value.val[0].data,					 attr->value.val[0].length,					 &decode_oid,					 &size);		if (ret) {		    hx509_set_error_string(context, 0, ret,					   "Failed to decode "					   "oid in signedAttrs");		    goto next_sigature;		}		match_oid = &decode_oid;	    }	    ALLOC(signed_data, 1);	    if (signed_data == NULL) {		if (match_oid == &decode_oid)		    der_free_oid(&decode_oid);		ret = ENOMEM;		hx509_clear_error_string(context);		goto next_sigature;	    }		    ASN1_MALLOC_ENCODE(CMSAttributes,			       signed_data->data,			       signed_data->length,			       &sa,			       &size, ret);	    if (ret) {		if (match_oid == &decode_oid)		    der_free_oid(&decode_oid);		free(signed_data);		hx509_clear_error_string(context);		goto next_sigature;	    }	    if (size != signed_data->length)		_hx509_abort("internal ASN.1 encoder error");	} else {	    signed_data = rk_UNCONST(signedContent);	    match_oid = oid_id_pkcs7_data();	}	if (der_heim_oid_cmp(match_oid, &sd.encapContentInfo.eContentType)) {	    ret = HX509_CMS_DATA_OID_MISMATCH;	    hx509_set_error_string(context, 0, ret,				   "Oid in message mismatch from the expected");	}	if (match_oid == &decode_oid)	    der_free_oid(&decode_oid);

⌨️ 快捷键说明

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