summaryrefslogtreecommitdiff
path: root/source4/heimdal/lib/hx509/cms.c
diff options
context:
space:
mode:
Diffstat (limited to 'source4/heimdal/lib/hx509/cms.c')
-rw-r--r--source4/heimdal/lib/hx509/cms.c53
1 files changed, 35 insertions, 18 deletions
diff --git a/source4/heimdal/lib/hx509/cms.c b/source4/heimdal/lib/hx509/cms.c
index 5506cee463..224c39086c 100644
--- a/source4/heimdal/lib/hx509/cms.c
+++ b/source4/heimdal/lib/hx509/cms.c
@@ -1170,6 +1170,7 @@ struct sigctx {
heim_octet_string content;
hx509_peer_info peer;
int cmsidflag;
+ int leafonly;
hx509_certs certs;
hx509_certs anchors;
hx509_certs pool;
@@ -1360,7 +1361,7 @@ sig_process(hx509_context context, void *ctx, hx509_cert cert)
if (sigctx->certs) {
unsigned int i;
- if (sigctx->pool) {
+ if (sigctx->pool && sigctx->leafonly == 0) {
_hx509_calculate_path(context,
HX509_CALCULATE_PATH_NO_ANCHOR,
time(NULL),
@@ -1415,6 +1416,12 @@ cert_process(hx509_context context, void *ctx, hx509_cert cert)
return ret;
}
+static int
+cmp_AlgorithmIdentifier(const AlgorithmIdentifier *p, const AlgorithmIdentifier *q)
+{
+ return der_heim_oid_cmp(&p->algorithm, &q->algorithm);
+}
+
int
hx509_cms_create_signed(hx509_context context,
int flags,
@@ -1427,7 +1434,7 @@ hx509_cms_create_signed(hx509_context context,
hx509_certs pool,
heim_octet_string *signed_data)
{
- unsigned int i;
+ unsigned int i, j;
hx509_name name;
int ret;
size_t size;
@@ -1454,9 +1461,22 @@ hx509_cms_create_signed(hx509_context context,
else
sigctx.cmsidflag = CMS_ID_SKI;
- ret = hx509_certs_init(context, "MEMORY:certs", 0, NULL, &sigctx.certs);
- if (ret)
- return ret;
+ /**
+ * Use HX509_CMS_SIGNATURE_LEAF_ONLY to only request leaf
+ * certificates to be added to the SignedData.
+ */
+ sigctx.leafonly = (flags & HX509_CMS_SIGNATURE_LEAF_ONLY) ? 1 : 0;
+
+ /**
+ * Use HX509_CMS_NO_CERTS to make the SignedData contain no
+ * certificates, overrides HX509_CMS_SIGNATURE_LEAF_ONLY.
+ */
+
+ if ((flags & HX509_CMS_SIGNATURE_NO_CERTS) == 0) {
+ ret = hx509_certs_init(context, "MEMORY:certs", 0, NULL, &sigctx.certs);
+ if (ret)
+ return ret;
+ }
sigctx.anchors = anchors;
sigctx.pool = pool;
@@ -1497,22 +1517,19 @@ hx509_cms_create_signed(hx509_context context,
}
if (sigctx.sd.signerInfos.len) {
- ALLOC_SEQ(&sigctx.sd.digestAlgorithms, sigctx.sd.signerInfos.len);
- if (sigctx.sd.digestAlgorithms.val == NULL) {
- ret = ENOMEM;
- hx509_clear_error_string(context);
- goto out;
- }
-
- /* XXX remove dups */
for (i = 0; i < sigctx.sd.signerInfos.len; i++) {
AlgorithmIdentifier *di =
&sigctx.sd.signerInfos.val[i].digestAlgorithm;
- ret = copy_AlgorithmIdentifier(di,
- &sigctx.sd.digestAlgorithms.val[i]);
- if (ret) {
- hx509_clear_error_string(context);
- goto out;
+
+ for (j = 0; j < sigctx.sd.digestAlgorithms.len; j++)
+ if (cmp_AlgorithmIdentifier(di, &sigctx.sd.digestAlgorithms.val[j]) == 0)
+ break;
+ if (j < sigctx.sd.digestAlgorithms.len) {
+ ret = add_DigestAlgorithmIdentifiers(&sigctx.sd.digestAlgorithms, di);
+ if (ret) {
+ hx509_clear_error_string(context);
+ goto out;
+ }
}
}
}