📄 cms.c
字号:
if (ret == 0) { ret = hx509_verify_signature(context, cert, &signer_info->signatureAlgorithm, signed_data, &signer_info->signature); if (ret) hx509_set_error_string(context, HX509_ERROR_APPEND, ret, "Failed to verify sigature in " "CMS SignedData"); } if (signed_data != signedContent) { der_free_octet_string(signed_data); free(signed_data); } if (ret) goto next_sigature; ret = hx509_verify_path(context, ctx, cert, certs); if (ret) goto next_sigature; ret = hx509_certs_add(context, *signer_certs, cert); if (ret) goto next_sigature; found_valid_sig++; next_sigature: if (cert) hx509_cert_free(cert); cert = NULL; } if (found_valid_sig == 0) { if (ret == 0) { ret = HX509_CMS_SIGNER_NOT_FOUND; hx509_set_error_string(context, 0, ret, "No signers where found"); } goto out; } ret = der_copy_oid(&sd.encapContentInfo.eContentType, contentType); if (ret) { hx509_clear_error_string(context); goto out; } content->data = malloc(signedContent->length); if (content->data == NULL) { hx509_clear_error_string(context); ret = ENOMEM; goto out; } content->length = signedContent->length; memcpy(content->data, signedContent->data, content->length);out: free_SignedData(&sd); if (certs) hx509_certs_free(&certs); if (ret) { if (*signer_certs) hx509_certs_free(signer_certs); der_free_oid(contentType); der_free_octet_string(content); } return ret;}static intadd_one_attribute(Attribute **attr, unsigned int *len, const heim_oid *oid, heim_octet_string *data){ void *d; int ret; d = realloc(*attr, sizeof((*attr)[0]) * (*len + 1)); if (d == NULL) return ENOMEM; (*attr) = d; ret = der_copy_oid(oid, &(*attr)[*len].type); if (ret) return ret; ALLOC_SEQ(&(*attr)[*len].value, 1); if ((*attr)[*len].value.val == NULL) { der_free_oid(&(*attr)[*len].type); return ENOMEM; } (*attr)[*len].value.val[0].data = data->data; (*attr)[*len].value.val[0].length = data->length; *len += 1; return 0;} /** * Decode SignedData and verify that the signature is correct. * * @param context A hx509 context. * @param flags * @param eContentType the type of the data. * @param data data to sign * @param length length of the data that data point to. * @param digest_alg digest algorithm to use, use NULL to get the * default or the peer determined algorithm. * @param cert certificate to use for sign the data. * @param peer info about the peer the message to send the message to, * like what digest algorithm to use. * @param anchors trust anchors that the client will use, used to * polulate the certificates included in the message * @param pool certificates to use in try to build the path to the * trust anchors. * @param signed_data the output of the function, free with * der_free_octet_string(). * * @ingroup hx509_cms */inthx509_cms_create_signed_1(hx509_context context, int flags, const heim_oid *eContentType, const void *data, size_t length, const AlgorithmIdentifier *digest_alg, hx509_cert cert, hx509_peer_info peer, hx509_certs anchors, hx509_certs pool, heim_octet_string *signed_data){ AlgorithmIdentifier digest; hx509_name name; SignerInfo *signer_info; heim_octet_string buf, content, sigdata = { 0, NULL }; SignedData sd; int ret; size_t size; hx509_path path; int cmsidflag = CMS_ID_SKI; memset(&sd, 0, sizeof(sd)); memset(&name, 0, sizeof(name)); memset(&path, 0, sizeof(path)); memset(&digest, 0, sizeof(digest)); content.data = rk_UNCONST(data); content.length = length; if (flags & HX509_CMS_SIGATURE_ID_NAME) cmsidflag = CMS_ID_NAME; if (_hx509_cert_private_key(cert) == NULL) { hx509_set_error_string(context, 0, HX509_PRIVATE_KEY_MISSING, "Private key missing for signing"); return HX509_PRIVATE_KEY_MISSING; } if (digest_alg == NULL) { ret = hx509_crypto_select(context, HX509_SELECT_DIGEST, _hx509_cert_private_key(cert), peer, &digest); } else { ret = copy_AlgorithmIdentifier(digest_alg, &digest); if (ret) hx509_clear_error_string(context); } if (ret) goto out; sd.version = CMSVersion_v3; if (eContentType == NULL) eContentType = oid_id_pkcs7_data(); der_copy_oid(eContentType, &sd.encapContentInfo.eContentType); /* */ if ((flags & HX509_CMS_SIGATURE_DETACHED) == 0) { ALLOC(sd.encapContentInfo.eContent, 1); if (sd.encapContentInfo.eContent == NULL) { hx509_clear_error_string(context); ret = ENOMEM; goto out; } sd.encapContentInfo.eContent->data = malloc(length); if (sd.encapContentInfo.eContent->data == NULL) { hx509_clear_error_string(context); ret = ENOMEM; goto out; } memcpy(sd.encapContentInfo.eContent->data, data, length); sd.encapContentInfo.eContent->length = length; } ALLOC_SEQ(&sd.signerInfos, 1); if (sd.signerInfos.val == NULL) { hx509_clear_error_string(context); ret = ENOMEM; goto out; } signer_info = &sd.signerInfos.val[0]; signer_info->version = 1; ret = fill_CMSIdentifier(cert, cmsidflag, &signer_info->sid); if (ret) { hx509_clear_error_string(context); goto out; } signer_info->signedAttrs = NULL; signer_info->unsignedAttrs = NULL; ret = copy_AlgorithmIdentifier(&digest, &signer_info->digestAlgorithm); if (ret) { hx509_clear_error_string(context); goto out; } /* * If it isn't pkcs7-data send signedAttributes */ if (der_heim_oid_cmp(eContentType, oid_id_pkcs7_data()) != 0) { CMSAttributes sa; heim_octet_string sig; ALLOC(signer_info->signedAttrs, 1); if (signer_info->signedAttrs == NULL) { ret = ENOMEM; goto out; } ret = _hx509_create_signature(context, NULL, &digest, &content, NULL, &sig); if (ret) goto out; ASN1_MALLOC_ENCODE(MessageDigest, buf.data, buf.length, &sig, &size, ret); der_free_octet_string(&sig); if (ret) { hx509_clear_error_string(context); goto out; } if (size != buf.length) _hx509_abort("internal ASN.1 encoder error"); ret = add_one_attribute(&signer_info->signedAttrs->val, &signer_info->signedAttrs->len, oid_id_pkcs9_messageDigest(), &buf); if (ret) { hx509_clear_error_string(context); goto out; } ASN1_MALLOC_ENCODE(ContentType, buf.data, buf.length, eContentType, &size, ret); if (ret) goto out; if (size != buf.length) _hx509_abort("internal ASN.1 encoder error"); ret = add_one_attribute(&signer_info->signedAttrs->val, &signer_info->signedAttrs->len, oid_id_pkcs9_contentType(), &buf); if (ret) { hx509_clear_error_string(context); goto out; } sa.val = signer_info->signedAttrs->val; sa.len = signer_info->signedAttrs->len; ASN1_MALLOC_ENCODE(CMSAttributes, sigdata.data, sigdata.length, &sa, &size, ret); if (ret) { hx509_clear_error_string(context); goto out; } if (size != sigdata.length) _hx509_abort("internal ASN.1 encoder error"); } else { sigdata.data = content.data; sigdata.length = content.length; } { AlgorithmIdentifier sigalg; ret = hx509_crypto_select(context, HX509_SELECT_PUBLIC_SIG, _hx509_cert_private_key(cert), peer, &sigalg); if (ret) goto out; ret = _hx509_create_signature(context, _hx509_cert_private_key(cert), &sigalg, &sigdata, &signer_info->signatureAlgorithm, &signer_info->signature); free_AlgorithmIdentifier(&sigalg); if (ret) goto out; } ALLOC_SEQ(&sd.digestAlgorithms, 1); if (sd.digestAlgorithms.val == NULL) { ret = ENOMEM; hx509_clear_error_string(context); goto out; } ret = copy_AlgorithmIdentifier(&digest, &sd.digestAlgorithms.val[0]); if (ret) { hx509_clear_error_string(context); goto out; } /* * Provide best effort path */ if (pool) { _hx509_calculate_path(context, HX509_CALCULATE_PATH_NO_ANCHOR, time(NULL), anchors, 0, cert, pool, &path); } else _hx509_path_append(context, &path, cert); if (path.len) { int i; ALLOC(sd.certificates, 1); if (sd.certificates == NULL) { hx509_clear_error_string(context); ret = ENOMEM; goto out; } ALLOC_SEQ(sd.certificates, path.len); if (sd.certificates->val == NULL) { hx509_clear_error_string(context); ret = ENOMEM; goto out; } for (i = 0; i < path.len; i++) { ret = hx509_cert_binary(context, path.val[i], &sd.certificates->val[i]); if (ret) { hx509_clear_error_string(context); goto out; } } } ASN1_MALLOC_ENCODE(SignedData, signed_data->data, signed_data->length, &sd, &size, ret); if (ret) { hx509_clear_error_string(context); goto out; } if (signed_data->length != size) _hx509_abort("internal ASN.1 encoder error");out: if (sigdata.data != content.data) der_free_octet_string(&sigdata); free_AlgorithmIdentifier(&digest); _hx509_path_free(&path); free_SignedData(&sd); return ret;}inthx509_cms_decrypt_encrypted(hx509_context context, hx509_lock lock, const void *data, size_t length, heim_oid *contentType, heim_octet_string *content){ heim_octet_string cont; CMSEncryptedData ed; AlgorithmIdentifier *ai; int ret; memset(content, 0, sizeof(*content)); memset(&cont, 0, sizeof(cont)); ret = decode_CMSEncryptedData(data, length, &ed, NULL); if (ret) { hx509_set_error_string(context, 0, ret, "Failed to decode CMSEncryptedData"); return ret; } if (ed.encryptedContentInfo.encryptedContent == NULL) { ret = HX509_CMS_NO_DATA_AVAILABLE; hx509_set_error_string(context, 0, ret, "No content in EncryptedData"); goto out; } ret = der_copy_oid(&ed.encryptedContentInfo.contentType, contentType); if (ret) { hx509_clear_error_string(context); goto out; } ai = &ed.encryptedContentInfo.contentEncryptionAlgorithm; if (ai->parameters == NULL) { ret = HX509_ALG_NOT_SUPP; hx509_clear_error_string(context); goto out; } ret = _hx509_pbe_decrypt(context, lock, ai, ed.encryptedContentInfo.encryptedContent, &cont); if (ret) goto out; *content = cont;out: if (ret) { if (cont.data) free(cont.data); } free_CMSEncryptedData(&ed); return ret;}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -