diff options
Diffstat (limited to 'source4/heimdal/lib/hx509/ks_p12.c')
-rw-r--r-- | source4/heimdal/lib/hx509/ks_p12.c | 95 |
1 files changed, 72 insertions, 23 deletions
diff --git a/source4/heimdal/lib/hx509/ks_p12.c b/source4/heimdal/lib/hx509/ks_p12.c index 0ca13de1eb3..6fd7cd10526 100644 --- a/source4/heimdal/lib/hx509/ks_p12.c +++ b/source4/heimdal/lib/hx509/ks_p12.c @@ -36,10 +36,12 @@ struct ks_pkcs12 { hx509_certs certs; char *fn; + unsigned int store_no_priv_keys; }; typedef int (*collector_func)(hx509_context, struct hx509_collector *, + int, const void *, size_t, const PKCS12_Attributes *); @@ -49,8 +51,9 @@ struct type { }; static void -parse_pkcs12_type(hx509_context, struct hx509_collector *, const heim_oid *, - const void *, size_t, const PKCS12_Attributes *); +parse_pkcs12_type(hx509_context, struct hx509_collector *, int, + const heim_oid *, const void *, size_t, + const PKCS12_Attributes *); static const PKCS12_Attribute * @@ -68,6 +71,7 @@ find_attribute(const PKCS12_Attributes *attrs, const heim_oid *oid) static int keyBag_parser(hx509_context context, struct hx509_collector *c, + int flags, const void *data, size_t length, const PKCS12_Attributes *attrs) { @@ -76,6 +80,9 @@ keyBag_parser(hx509_context context, const heim_octet_string *os = NULL; int ret; + if (flags & HX509_CERTS_NO_PRIVATE_KEYS) + return 0; + attr = find_attribute(attrs, &asn1_oid_id_pkcs_9_at_localKeyId); if (attr) os = &attr->attrValues; @@ -97,6 +104,7 @@ keyBag_parser(hx509_context context, static int ShroudedKeyBag_parser(hx509_context context, struct hx509_collector *c, + int flags, const void *data, size_t length, const PKCS12_Attributes *attrs) { @@ -119,7 +127,8 @@ ShroudedKeyBag_parser(hx509_context context, if (ret) return ret; - ret = keyBag_parser(context, c, content.data, content.length, attrs); + ret = keyBag_parser(context, c, flags, content.data, content.length, + attrs); der_free_octet_string(&content); return ret; } @@ -127,9 +136,11 @@ ShroudedKeyBag_parser(hx509_context context, static int certBag_parser(hx509_context context, struct hx509_collector *c, + int flags, const void *data, size_t length, const PKCS12_Attributes *attrs) { + heim_error_t error = NULL; heim_octet_string os; hx509_cert cert; PKCS12_CertBag cb; @@ -152,10 +163,13 @@ certBag_parser(hx509_context context, if (ret) return ret; - ret = hx509_cert_init_data(context, os.data, os.length, &cert); + cert = hx509_cert_init_data(context, os.data, os.length, &error); der_free_octet_string(&os); - if (ret) + if (cert == NULL) { + ret = heim_error_get_code(error); + heim_release(error); return ret; + } ret = _hx509_collector_certs_add(context, c, cert); if (ret) { @@ -187,6 +201,7 @@ certBag_parser(hx509_context context, static int parse_safe_content(hx509_context context, struct hx509_collector *c, + int flags, const unsigned char *p, size_t len) { PKCS12_SafeContents sc; @@ -202,6 +217,7 @@ parse_safe_content(hx509_context context, for (i = 0; i < sc.len ; i++) parse_pkcs12_type(context, c, + flags, &sc.val[i].bagId, sc.val[i].bagValue.data, sc.val[i].bagValue.length, @@ -214,6 +230,7 @@ parse_safe_content(hx509_context context, static int safeContent_parser(hx509_context context, struct hx509_collector *c, + int flags, const void *data, size_t length, const PKCS12_Attributes *attrs) { @@ -223,7 +240,7 @@ safeContent_parser(hx509_context context, ret = decode_PKCS12_OctetString(data, length, &os, NULL); if (ret) return ret; - ret = parse_safe_content(context, c, os.data, os.length); + ret = parse_safe_content(context, c, flags, os.data, os.length); der_free_octet_string(&os); return ret; } @@ -231,6 +248,7 @@ safeContent_parser(hx509_context context, static int encryptedData_parser(hx509_context context, struct hx509_collector *c, + int flags, const void *data, size_t length, const PKCS12_Attributes *attrs) { @@ -249,7 +267,8 @@ encryptedData_parser(hx509_context context, return ret; if (der_heim_oid_cmp(&contentType, &asn1_oid_id_pkcs7_data) == 0) - ret = parse_safe_content(context, c, content.data, content.length); + ret = parse_safe_content(context, c, flags, + content.data, content.length); der_free_octet_string(&content); der_free_oid(&contentType); @@ -259,6 +278,7 @@ encryptedData_parser(hx509_context context, static int envelopedData_parser(hx509_context context, struct hx509_collector *c, + int flags, const void *data, size_t length, const PKCS12_Attributes *attrs) { @@ -286,7 +306,8 @@ envelopedData_parser(hx509_context context, } if (der_heim_oid_cmp(&contentType, &asn1_oid_id_pkcs7_data) == 0) - ret = parse_safe_content(context, c, content.data, content.length); + ret = parse_safe_content(context, c, flags, + content.data, content.length); der_free_octet_string(&content); der_free_oid(&contentType); @@ -307,6 +328,7 @@ struct type bagtypes[] = { static void parse_pkcs12_type(hx509_context context, struct hx509_collector *c, + int flags, const heim_oid *oid, const void *data, size_t length, const PKCS12_Attributes *attrs) @@ -315,7 +337,7 @@ parse_pkcs12_type(hx509_context context, for (i = 0; i < sizeof(bagtypes)/sizeof(bagtypes[0]); i++) if (der_heim_oid_cmp(bagtypes[i].oid, oid) == 0) - (*bagtypes[i].func)(context, c, data, length, attrs); + (*bagtypes[i].func)(context, c, flags, data, length, attrs); } static int @@ -334,6 +356,12 @@ p12_init(hx509_context context, *data = NULL; + if (residue == NULL || residue[0] == '\0') { + hx509_set_error_string(context, 0, EINVAL, + "PKCS#12 file not specified"); + return EINVAL; + } + if (lock == NULL) lock = _hx509_empty_lock; @@ -419,6 +447,7 @@ p12_init(hx509_context context, for (i = 0; i < as.len; i++) parse_pkcs12_type(context, c, + flags, &as.val[i].contentType, as.val[i].content->data, as.val[i].content->length, @@ -482,10 +511,15 @@ addBag(hx509_context context, return 0; } -static int -store_func(hx509_context context, void *ctx, hx509_cert c) +struct store_func_ctx { + PKCS12_AuthenticatedSafe as; + int store_flags; +}; + +static int HX509_LIB_CALL +store_func(hx509_context context, void *d, hx509_cert c) { - PKCS12_AuthenticatedSafe *as = ctx; + struct store_func_ctx *ctx = d; PKCS12_OctetString os; PKCS12_CertBag cb; size_t size; @@ -518,9 +552,11 @@ store_func(hx509_context context, void *ctx, hx509_cert c) if (ret) goto out; - ret = addBag(context, as, &asn1_oid_id_pkcs12_certBag, os.data, os.length); + ret = addBag(context, &ctx->as, &asn1_oid_id_pkcs12_certBag, os.data, + os.length); - if (_hx509_cert_private_key_exportable(c)) { + if (_hx509_cert_private_key_exportable(c) && + !(ctx->store_flags & HX509_CERTS_STORE_NO_PRIVATE_KEYS)) { hx509_private_key key = _hx509_cert_private_key(c); PKCS8PrivateKeyInfo pki; @@ -551,7 +587,8 @@ store_func(hx509_context context, void *ctx, hx509_cert c) if (ret) return ret; - ret = addBag(context, as, &asn1_oid_id_pkcs12_keyBag, os.data, os.length); + ret = addBag(context, &ctx->as, &asn1_oid_id_pkcs12_keyBag, os.data, + os.length); if (ret) return ret; } @@ -566,21 +603,22 @@ p12_store(hx509_context context, { struct ks_pkcs12 *p12 = data; PKCS12_PFX pfx; - PKCS12_AuthenticatedSafe as; + struct store_func_ctx ctx; PKCS12_OctetString asdata; size_t size; int ret; - memset(&as, 0, sizeof(as)); + memset(&ctx, 0, sizeof(ctx)); memset(&pfx, 0, sizeof(pfx)); + ctx.store_flags = flags; - ret = hx509_certs_iter_f(context, p12->certs, store_func, &as); + ret = hx509_certs_iter_f(context, p12->certs, store_func, &ctx); if (ret) goto out; ASN1_MALLOC_ENCODE(PKCS12_AuthenticatedSafe, asdata.data, asdata.length, - &as, &size, ret); - free_PKCS12_AuthenticatedSafe(&as); + &ctx.as, &size, ret); + free_PKCS12_AuthenticatedSafe(&ctx.as); if (ret) return ret; @@ -632,7 +670,7 @@ p12_store(hx509_context context, free(asdata.data); out: - free_PKCS12_AuthenticatedSafe(&as); + free_PKCS12_AuthenticatedSafe(&ctx.as); free_PKCS12_PFX(&pfx); return ret; @@ -687,6 +725,13 @@ p12_iter_end(hx509_context context, return hx509_certs_end_seq(context, p12->certs, cursor); } +static int +p12_destroy(hx509_context context, hx509_certs certs, void *data) +{ + struct ks_pkcs12 *p12 = data; + return _hx509_erase_file(context, p12->fn); +} + static struct hx509_keyset_ops keyset_pkcs12 = { "PKCS12", 0, @@ -697,10 +742,14 @@ static struct hx509_keyset_ops keyset_pkcs12 = { NULL, p12_iter_start, p12_iter, - p12_iter_end + p12_iter_end, + NULL, + NULL, + NULL, + p12_destroy }; -void +HX509_LIB_FUNCTION void HX509_LIB_CALL _hx509_ks_pkcs12_register(hx509_context context) { _hx509_ks_register(context, &keyset_pkcs12); |