[PATCH 1/2] acpi: video: add function to support unregister backlight
From: "Lee, Chun-Yi" There have situation we unregister whole acpi/video driver by downstream driver just want to remove backlight control interface of acpi/video. It caues we lost other functions of acpi/video, e.g. transfer acpi event to input event. So, this patch add a new function, find_video_unregister_backlight, it provide the interface let downstream driver can tell acpi/video to unregister backlight interface of all acpi video devices. Then we can keep functions of acpi/video but only remove backlight support. Reference: bko#35622 https://bugzilla.kernel.org/show_bug.cgi?id=35622 Tested-by: Andrzej Krentosz Cc: Carlos Corbacho Cc: Matthew Garrett Cc: Dmitry Torokhov Cc: Corentin Chary Cc: Rafael J. Wysocki Cc: Aaron Lu Cc: Thomas Renninger Signed-off-by: Lee, Chun-Yi --- drivers/acpi/video.c | 46 ++ include/acpi/video.h | 2 ++ 2 files changed, 48 insertions(+) diff --git a/drivers/acpi/video.c b/drivers/acpi/video.c index 313f959..acd2e7a 100644 --- a/drivers/acpi/video.c +++ b/drivers/acpi/video.c @@ -1793,6 +1793,52 @@ static int __init intel_opregion_present(void) return opregion; } +static acpi_status +find_video_unregister_backlight(acpi_handle handle, u32 lvl, void *context, + void **rv) +{ + struct acpi_device *acpi_dev; + struct acpi_video_bus *video = NULL; + struct acpi_video_device *dev, *next; + + if (acpi_bus_get_device(handle, _dev)) + return AE_OK; + + if (!acpi_match_device_ids(acpi_dev, video_device_ids)) { + video = acpi_driver_data(acpi_dev); + acpi_video_bus_stop_devices(video); + mutex_lock(>device_list_lock); + list_for_each_entry_safe(dev, next, >video_device_list, + entry) { + if (dev->backlight) { + backlight_device_unregister(dev->backlight); + dev->backlight = NULL; + kfree(dev->brightness->levels); + kfree(dev->brightness); + } + } + mutex_unlock(>device_list_lock); + acpi_video_bus_start_devices(video); + } + return AE_OK; +} + +void acpi_video_backlight_unregister(void) +{ + if (!register_count) { + /* +* If the acpi video bus is already unloaded, don't +* unregister backlight of devices and return directly. +*/ + return; + } + acpi_walk_namespace(ACPI_TYPE_DEVICE, ACPI_ROOT_OBJECT, + ACPI_UINT32_MAX, find_video_unregister_backlight, + NULL, NULL, NULL); + return; +} +EXPORT_SYMBOL(acpi_video_backlight_unregister); + int acpi_video_register(void) { int result = 0; diff --git a/include/acpi/video.h b/include/acpi/video.h index 61109f2..1e810a1 100644 --- a/include/acpi/video.h +++ b/include/acpi/video.h @@ -19,11 +19,13 @@ struct acpi_device; #if (defined CONFIG_ACPI_VIDEO || defined CONFIG_ACPI_VIDEO_MODULE) extern int acpi_video_register(void); extern void acpi_video_unregister(void); +extern void acpi_video_backlight_unregister(void); extern int acpi_video_get_edid(struct acpi_device *device, int type, int device_id, void **edid); #else static inline int acpi_video_register(void) { return 0; } static inline void acpi_video_unregister(void) { return; } +static inline void acpi_video_backlight_unregister(void) { return; } static inline int acpi_video_get_edid(struct acpi_device *device, int type, int device_id, void **edid) { -- 1.8.1.4 -- To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/
[PATCH 2/2] acer-wmi: add Acer Aspire 5750G to video vendor list but keep acpi video driver
From: Lee, Chun-Yi After Andrzej's testing, we found the acpi backlight methods broken on Acer Aspire 5750G but the i915 backlight control works when we set to vendor mode. And, we still want to keep the acpi/video driver for transfer acpi event to key event but not unregister whole acpi/video driver. This patch introduced a new capability flag is ACER_CAP_KEEP_VIDEO_KEY, it indicates the machine works fine with acpi/video driver for key event but want to unregister the backlight interface of acpi/video. Reference: bko#35622 https://bugzilla.kernel.org/show_bug.cgi?id=35622 Tested-by: Andrzej Krentosz Cc: Carlos Corbacho Cc: Matthew Garrett Cc: Dmitry Torokhov Cc: Corentin Chary Cc: Rafael J. Wysocki Cc: Aaron Lu Cc: Thomas Renninger Signed-off-by: Lee, Chun-Yi --- drivers/platform/x86/acer-wmi.c | 20 1 files changed, 20 insertions(+), 0 deletions(-) diff --git a/drivers/platform/x86/acer-wmi.c b/drivers/platform/x86/acer-wmi.c index c9076bd..2a02409 100644 --- a/drivers/platform/x86/acer-wmi.c +++ b/drivers/platform/x86/acer-wmi.c @@ -207,6 +207,7 @@ struct hotkey_function_type_aa { #define ACER_CAP_BRIGHTNESS(1<<3) #define ACER_CAP_THREEG(1<<4) #define ACER_CAP_ACCEL (1<<5) +#define ACER_CAP_KEEP_VIDEO_KEY(1<<6) #define ACER_CAP_ANY (0x) /* @@ -539,6 +540,15 @@ static int video_set_backlight_video_vendor(const struct dmi_system_id *d) return 0; } +static int video_set_backlight_video_vendor_keep_acpi_video( + const struct dmi_system_id *d) +{ + video_set_backlight_video_vendor(d); + interface->capability |= ACER_CAP_KEEP_VIDEO_KEY; + pr_info("Keep acpi video driver for emit keycode against backlight change\n"); + return 0; +} + static const struct dmi_system_id video_vendor_dmi_table[] = { { .callback = video_set_backlight_video_vendor, @@ -572,6 +582,14 @@ static const struct dmi_system_id video_vendor_dmi_table[] = { DMI_MATCH(DMI_PRODUCT_NAME, "Aspire 5750"), }, }, + { + .callback = video_set_backlight_video_vendor_keep_acpi_video, + .ident = "Acer Aspire 5750G", + .matches = { + DMI_MATCH(DMI_BOARD_VENDOR, "Acer"), + DMI_MATCH(DMI_PRODUCT_NAME, "Aspire 5750G"), + }, + }, {} }; @@ -2228,6 +2246,8 @@ static int __init acer_wmi_init(void) if (acpi_video_backlight_support()) { interface->capability &= ~ACER_CAP_BRIGHTNESS; pr_info("Brightness must be controlled by acpi video driver\n"); + } else if (interface->capability & ACER_CAP_KEEP_VIDEO_KEY) { + acpi_video_backlight_unregister(); } else { pr_info("Disabling ACPI video driver\n"); acpi_video_unregister(); -- 1.6.0.2 -- To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/
[PATCH 2/2] acer-wmi: add Acer Aspire 5750G to video vendor list but keep acpi video driver
From: Lee, Chun-Yi j...@suse.com After Andrzej's testing, we found the acpi backlight methods broken on Acer Aspire 5750G but the i915 backlight control works when we set to vendor mode. And, we still want to keep the acpi/video driver for transfer acpi event to key event but not unregister whole acpi/video driver. This patch introduced a new capability flag is ACER_CAP_KEEP_VIDEO_KEY, it indicates the machine works fine with acpi/video driver for key event but want to unregister the backlight interface of acpi/video. Reference: bko#35622 https://bugzilla.kernel.org/show_bug.cgi?id=35622 Tested-by: Andrzej Krentosz endr...@gmail.com Cc: Carlos Corbacho car...@strangeworlds.co.uk Cc: Matthew Garrett m...@redhat.com Cc: Dmitry Torokhov d...@mail.ru Cc: Corentin Chary corenti...@iksaif.net Cc: Rafael J. Wysocki r...@sisk.pl Cc: Aaron Lu aaron...@intel.com Cc: Thomas Renninger tr...@suse.de Signed-off-by: Lee, Chun-Yi j...@suse.com --- drivers/platform/x86/acer-wmi.c | 20 1 files changed, 20 insertions(+), 0 deletions(-) diff --git a/drivers/platform/x86/acer-wmi.c b/drivers/platform/x86/acer-wmi.c index c9076bd..2a02409 100644 --- a/drivers/platform/x86/acer-wmi.c +++ b/drivers/platform/x86/acer-wmi.c @@ -207,6 +207,7 @@ struct hotkey_function_type_aa { #define ACER_CAP_BRIGHTNESS(13) #define ACER_CAP_THREEG(14) #define ACER_CAP_ACCEL (15) +#define ACER_CAP_KEEP_VIDEO_KEY(16) #define ACER_CAP_ANY (0x) /* @@ -539,6 +540,15 @@ static int video_set_backlight_video_vendor(const struct dmi_system_id *d) return 0; } +static int video_set_backlight_video_vendor_keep_acpi_video( + const struct dmi_system_id *d) +{ + video_set_backlight_video_vendor(d); + interface-capability |= ACER_CAP_KEEP_VIDEO_KEY; + pr_info(Keep acpi video driver for emit keycode against backlight change\n); + return 0; +} + static const struct dmi_system_id video_vendor_dmi_table[] = { { .callback = video_set_backlight_video_vendor, @@ -572,6 +582,14 @@ static const struct dmi_system_id video_vendor_dmi_table[] = { DMI_MATCH(DMI_PRODUCT_NAME, Aspire 5750), }, }, + { + .callback = video_set_backlight_video_vendor_keep_acpi_video, + .ident = Acer Aspire 5750G, + .matches = { + DMI_MATCH(DMI_BOARD_VENDOR, Acer), + DMI_MATCH(DMI_PRODUCT_NAME, Aspire 5750G), + }, + }, {} }; @@ -2228,6 +2246,8 @@ static int __init acer_wmi_init(void) if (acpi_video_backlight_support()) { interface-capability = ~ACER_CAP_BRIGHTNESS; pr_info(Brightness must be controlled by acpi video driver\n); + } else if (interface-capability ACER_CAP_KEEP_VIDEO_KEY) { + acpi_video_backlight_unregister(); } else { pr_info(Disabling ACPI video driver\n); acpi_video_unregister(); -- 1.6.0.2 -- To unsubscribe from this list: send the line unsubscribe linux-kernel in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/
[PATCH 1/2] acpi: video: add function to support unregister backlight
From: Lee, Chun-Yi j...@suse.com There have situation we unregister whole acpi/video driver by downstream driver just want to remove backlight control interface of acpi/video. It caues we lost other functions of acpi/video, e.g. transfer acpi event to input event. So, this patch add a new function, find_video_unregister_backlight, it provide the interface let downstream driver can tell acpi/video to unregister backlight interface of all acpi video devices. Then we can keep functions of acpi/video but only remove backlight support. Reference: bko#35622 https://bugzilla.kernel.org/show_bug.cgi?id=35622 Tested-by: Andrzej Krentosz endr...@gmail.com Cc: Carlos Corbacho car...@strangeworlds.co.uk Cc: Matthew Garrett m...@redhat.com Cc: Dmitry Torokhov d...@mail.ru Cc: Corentin Chary corenti...@iksaif.net Cc: Rafael J. Wysocki r...@sisk.pl Cc: Aaron Lu aaron...@intel.com Cc: Thomas Renninger tr...@suse.de Signed-off-by: Lee, Chun-Yi j...@suse.com --- drivers/acpi/video.c | 46 ++ include/acpi/video.h | 2 ++ 2 files changed, 48 insertions(+) diff --git a/drivers/acpi/video.c b/drivers/acpi/video.c index 313f959..acd2e7a 100644 --- a/drivers/acpi/video.c +++ b/drivers/acpi/video.c @@ -1793,6 +1793,52 @@ static int __init intel_opregion_present(void) return opregion; } +static acpi_status +find_video_unregister_backlight(acpi_handle handle, u32 lvl, void *context, + void **rv) +{ + struct acpi_device *acpi_dev; + struct acpi_video_bus *video = NULL; + struct acpi_video_device *dev, *next; + + if (acpi_bus_get_device(handle, acpi_dev)) + return AE_OK; + + if (!acpi_match_device_ids(acpi_dev, video_device_ids)) { + video = acpi_driver_data(acpi_dev); + acpi_video_bus_stop_devices(video); + mutex_lock(video-device_list_lock); + list_for_each_entry_safe(dev, next, video-video_device_list, + entry) { + if (dev-backlight) { + backlight_device_unregister(dev-backlight); + dev-backlight = NULL; + kfree(dev-brightness-levels); + kfree(dev-brightness); + } + } + mutex_unlock(video-device_list_lock); + acpi_video_bus_start_devices(video); + } + return AE_OK; +} + +void acpi_video_backlight_unregister(void) +{ + if (!register_count) { + /* +* If the acpi video bus is already unloaded, don't +* unregister backlight of devices and return directly. +*/ + return; + } + acpi_walk_namespace(ACPI_TYPE_DEVICE, ACPI_ROOT_OBJECT, + ACPI_UINT32_MAX, find_video_unregister_backlight, + NULL, NULL, NULL); + return; +} +EXPORT_SYMBOL(acpi_video_backlight_unregister); + int acpi_video_register(void) { int result = 0; diff --git a/include/acpi/video.h b/include/acpi/video.h index 61109f2..1e810a1 100644 --- a/include/acpi/video.h +++ b/include/acpi/video.h @@ -19,11 +19,13 @@ struct acpi_device; #if (defined CONFIG_ACPI_VIDEO || defined CONFIG_ACPI_VIDEO_MODULE) extern int acpi_video_register(void); extern void acpi_video_unregister(void); +extern void acpi_video_backlight_unregister(void); extern int acpi_video_get_edid(struct acpi_device *device, int type, int device_id, void **edid); #else static inline int acpi_video_register(void) { return 0; } static inline void acpi_video_unregister(void) { return; } +static inline void acpi_video_backlight_unregister(void) { return; } static inline int acpi_video_get_edid(struct acpi_device *device, int type, int device_id, void **edid) { -- 1.8.1.4 -- To unsubscribe from this list: send the line unsubscribe linux-kernel in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/
[PATCH v2] MODSIGN: Fix including certificate twice when the signing_key.x509 already exists
This issue was found in devel-pekey branch on linux-modsign.git tree. The x509_certificate_list includes certificate twice when the signing_key.x509 already exists. We can reproduce this issue by making kernel twice, the build log of second time looks like this: ... CHK kernel/config_data.h CERTS kernel/x509_certificate_list - Including cert /ramdisk/working/joey/linux-modsign/signing_key.x509 - Including cert signing_key.x509 ... Actually the build path was the same with the srctree path when building kernel. It causes the size of bzImage increased by packaging certificates twice. v2: Using '$(shell /bin/pwd)' instead of '$(shell pwd)' for more reliable between different shells. Acked-by: David Howells Cc: Rusty Russell Cc: Josh Boyer Cc: Randy Dunlap Cc: Herbert Xu Cc: "David S. Miller" Cc: Michal Marek Signed-off-by: Chun-Yi Lee --- kernel/Makefile |5 - 1 files changed, 4 insertions(+), 1 deletions(-) diff --git a/kernel/Makefile b/kernel/Makefile index 0ca8c0a..3b854ce 100644 --- a/kernel/Makefile +++ b/kernel/Makefile @@ -142,7 +142,10 @@ $(obj)/timeconst.h: $(src)/timeconst.pl FORCE # ### ifeq ($(CONFIG_SYSTEM_TRUSTED_KEYRING),y) -X509_CERTIFICATES-y := $(wildcard *.x509) $(wildcard $(srctree)/*.x509) +X509_CERTIFICATES-y := $(wildcard *.x509) +ifneq ($(shell /bin/pwd), $(srctree)) +X509_CERTIFICATES-y += $(wildcard $(srctree)/*.x509) +endif X509_CERTIFICATES-$(CONFIG_MODULE_SIG) += signing_key.x509 X509_CERTIFICATES := $(sort $(X509_CERTIFICATES-y)) -- 1.6.0.2 -- To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/
[PATCH v2] MODSIGN: Fix including certificate twice when the signing_key.x509 already exists
This issue was found in devel-pekey branch on linux-modsign.git tree. The x509_certificate_list includes certificate twice when the signing_key.x509 already exists. We can reproduce this issue by making kernel twice, the build log of second time looks like this: ... CHK kernel/config_data.h CERTS kernel/x509_certificate_list - Including cert /ramdisk/working/joey/linux-modsign/signing_key.x509 - Including cert signing_key.x509 ... Actually the build path was the same with the srctree path when building kernel. It causes the size of bzImage increased by packaging certificates twice. v2: Using '$(shell /bin/pwd)' instead of '$(shell pwd)' for more reliable between different shells. Acked-by: David Howells dhowe...@redhat.com Cc: Rusty Russell ru...@rustcorp.com.au Cc: Josh Boyer jwbo...@redhat.com Cc: Randy Dunlap rdun...@xenotime.net Cc: Herbert Xu herb...@gondor.apana.org.au Cc: David S. Miller da...@davemloft.net Cc: Michal Marek mma...@suse.com Signed-off-by: Chun-Yi Lee j...@suse.com --- kernel/Makefile |5 - 1 files changed, 4 insertions(+), 1 deletions(-) diff --git a/kernel/Makefile b/kernel/Makefile index 0ca8c0a..3b854ce 100644 --- a/kernel/Makefile +++ b/kernel/Makefile @@ -142,7 +142,10 @@ $(obj)/timeconst.h: $(src)/timeconst.pl FORCE # ### ifeq ($(CONFIG_SYSTEM_TRUSTED_KEYRING),y) -X509_CERTIFICATES-y := $(wildcard *.x509) $(wildcard $(srctree)/*.x509) +X509_CERTIFICATES-y := $(wildcard *.x509) +ifneq ($(shell /bin/pwd), $(srctree)) +X509_CERTIFICATES-y += $(wildcard $(srctree)/*.x509) +endif X509_CERTIFICATES-$(CONFIG_MODULE_SIG) += signing_key.x509 X509_CERTIFICATES := $(sort $(X509_CERTIFICATES-y)) -- 1.6.0.2 -- To unsubscribe from this list: send the line unsubscribe linux-kernel in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/
[PATCH] MODSIGN: Fix including certificate twice when the signing_key.x509 already exists
This issue was found in devel-pekey branch on linux-modsign.git tree. The x509_certificate_list includes certificate twice when the signing_key.x509 already exists. We can reproduce this issue by making kernel twice, the build log of second time looks like this: ... CHK kernel/config_data.h CERTS kernel/x509_certificate_list - Including cert /ramdisk/working/joey/linux-modsign/signing_key.x509 - Including cert signing_key.x509 ... Actually the build path was the same with the srctree path when building kernel. It causes the size of bzImage increased by packaging certificates twice. Cc: David Howells Cc: Rusty Russell Cc: Josh Boyer Cc: Randy Dunlap Cc: Herbert Xu Cc: "David S. Miller" Cc: Michal Marek Signed-off-by: Chun-Yi Lee --- kernel/Makefile |5 - 1 files changed, 4 insertions(+), 1 deletions(-) diff --git a/kernel/Makefile b/kernel/Makefile index 0ca8c0a..ecbe73f 100644 --- a/kernel/Makefile +++ b/kernel/Makefile @@ -142,7 +142,10 @@ $(obj)/timeconst.h: $(src)/timeconst.pl FORCE # ### ifeq ($(CONFIG_SYSTEM_TRUSTED_KEYRING),y) -X509_CERTIFICATES-y := $(wildcard *.x509) $(wildcard $(srctree)/*.x509) +X509_CERTIFICATES-y := $(wildcard *.x509) +ifneq ($(shell pwd), $(srctree)) +X509_CERTIFICATES-y += $(wildcard $(srctree)/*.x509) +endif X509_CERTIFICATES-$(CONFIG_MODULE_SIG) += signing_key.x509 X509_CERTIFICATES := $(sort $(X509_CERTIFICATES-y)) -- 1.6.4.2 -- To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/
[PATCH] MODSIGN: Fix including certificate twice when the signing_key.x509 already exists
This issue was found in devel-pekey branch on linux-modsign.git tree. The x509_certificate_list includes certificate twice when the signing_key.x509 already exists. We can reproduce this issue by making kernel twice, the build log of second time looks like this: ... CHK kernel/config_data.h CERTS kernel/x509_certificate_list - Including cert /ramdisk/working/joey/linux-modsign/signing_key.x509 - Including cert signing_key.x509 ... Actually the build path was the same with the srctree path when building kernel. It causes the size of bzImage increased by packaging certificates twice. Cc: David Howells dhowe...@redhat.com Cc: Rusty Russell ru...@rustcorp.com.au Cc: Josh Boyer jwbo...@redhat.com Cc: Randy Dunlap rdun...@xenotime.net Cc: Herbert Xu herb...@gondor.apana.org.au Cc: David S. Miller da...@davemloft.net Cc: Michal Marek mma...@suse.com Signed-off-by: Chun-Yi Lee j...@suse.com --- kernel/Makefile |5 - 1 files changed, 4 insertions(+), 1 deletions(-) diff --git a/kernel/Makefile b/kernel/Makefile index 0ca8c0a..ecbe73f 100644 --- a/kernel/Makefile +++ b/kernel/Makefile @@ -142,7 +142,10 @@ $(obj)/timeconst.h: $(src)/timeconst.pl FORCE # ### ifeq ($(CONFIG_SYSTEM_TRUSTED_KEYRING),y) -X509_CERTIFICATES-y := $(wildcard *.x509) $(wildcard $(srctree)/*.x509) +X509_CERTIFICATES-y := $(wildcard *.x509) +ifneq ($(shell pwd), $(srctree)) +X509_CERTIFICATES-y += $(wildcard $(srctree)/*.x509) +endif X509_CERTIFICATES-$(CONFIG_MODULE_SIG) += signing_key.x509 X509_CERTIFICATES := $(sort $(X509_CERTIFICATES-y)) -- 1.6.4.2 -- To unsubscribe from this list: send the line unsubscribe linux-kernel in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/
[PATCH v2] X.509: Support parse long form of length octets in Authority Key Identifier
Per X.509 spec in 4.2.1.1 section, the structure of Authority Key Identifier Extension is: AuthorityKeyIdentifier ::= SEQUENCE { keyIdentifier [0] KeyIdentifier OPTIONAL, authorityCertIssuer [1] GeneralNamesOPTIONAL, authorityCertSerialNumber [2] CertificateSerialNumber OPTIONAL } KeyIdentifier ::= OCTET STRING When a certificate also provides authorityCertIssuer and authorityCertSerialNumber then the length of AuthorityKeyIdentifier SEQUENCE is likely to long form format. e.g. The example certificate demos/tunala/A-server.pem in openssl source: X509v3 Authority Key Identifier: keyid:49:FB:45:72:12:C4:CC:E1:45:A1:D3:08:9E:95:C4:2C:6D:55:3F:17 DirName:/C=NZ/L=Wellington/O=Really Irresponsible Authorisation Authority (RIAA)/OU=Cert-stamping/CN=Jackov al-Trades/emailAddress=none@fake.domain serial:00 Current parsing rule of OID_authorityKeyIdentifier only take care the short form format, it causes load certificate to modsign_keyring fail: [ 12.061147] X.509: Extension: 47 [ 12.075121] MODSIGN: Problem loading in-kernel X.509 certificate (-74) So, this patch add the parsing rule for support long form format against Authority Key Identifier. v2: - Removed comma from author's name. - Moved 'Short Form length' comment inside the if-body. - Changed the type of sub to size_t. - Use ASN1_INDEFINITE_LENGTH rather than writing 0x80 and 127. - Moved the key_len's value assignment before alter v. - Fixed the typo of octets. - Add 2 to v before entering the loop for calculate the length. - Removed the comment of check vlen. Cc: David Howells Cc: Rusty Russell Cc: Josh Boyer Cc: Randy Dunlap Cc: Herbert Xu Cc: "David S. Miller" Signed-off-by: Chun-Yi Lee --- crypto/asymmetric_keys/x509_cert_parser.c | 55 1 files changed, 47 insertions(+), 8 deletions(-) diff --git a/crypto/asymmetric_keys/x509_cert_parser.c b/crypto/asymmetric_keys/x509_cert_parser.c index 7fabc4c..59ab6d2 100644 --- a/crypto/asymmetric_keys/x509_cert_parser.c +++ b/crypto/asymmetric_keys/x509_cert_parser.c @@ -373,6 +373,9 @@ int rsa_extract_mpi(void *context, size_t hdrlen, return 0; } +/* The keyIdentifier in AuthorityKeyIdentifier SEQUENCE is tag(CONT,PRIM,0) */ +#define SEQ_TAG_KEYID (ASN1_CONT << 6) + /* * Process certificate extensions that are used to qualify the certificate. */ @@ -407,21 +410,57 @@ int x509_process_extension(void *context, size_t hdrlen, } if (ctx->last_oid == OID_authorityKeyIdentifier) { + size_t key_len; + /* Get hold of the CA key fingerprint */ if (vlen < 5) return -EBADMSG; - if (v[0] != (ASN1_SEQ | (ASN1_CONS << 5)) || - v[1] != vlen - 2 || - v[2] != (ASN1_CONT << 6) || - v[3] != vlen - 4) + + /* Authority Key Identifier must be a Constructed SEQUENCE */ + if (v[0] != (ASN1_SEQ | (ASN1_CONS << 5))) return -EBADMSG; - v += 4; - vlen -= 4; - f = kmalloc(vlen * 2 + 1, GFP_KERNEL); + /* Authority Key Identifier is not indefinite length */ + if (unlikely(vlen == ASN1_INDEFINITE_LENGTH)) + return -EBADMSG; + + if (vlen < ASN1_INDEFINITE_LENGTH) { + /* Short Form length */ + if (v[1] != vlen - 2 || + v[2] != SEQ_TAG_KEYID || + v[3] != vlen - 4) + return -EBADMSG; + + key_len = v[3]; + v += 4; + } else { + /* Long Form length */ + size_t seq_len = 0; + size_t sub = v[1] - ASN1_INDEFINITE_LENGTH; + + if (sub > 2) + return -EBADMSG; + + /* calculate the length from subsequent octets */ + v += 2; + for (i = 0; i < sub; i++) { + seq_len <<= 8; + seq_len |= v[i]; + } + + if (seq_len != vlen - 2 - sub || + v[sub] != SEQ_TAG_KEYID || + v[sub + 1] > vlen - 4 - sub) + return -EBADMSG; + + key_len = v[sub + 1]; + v += (sub + 2); + } + + f = kmalloc(key_len * 2 + 1, GFP_KERNEL); if (!f) return -ENOMEM; - for (i = 0; i < vlen; i++) + for (i = 0; i < key_len; i++) sprintf(f + i * 2, "%02x", v[i]);
[PATCH v2] X.509: Support parse long form of length octets in Authority Key Identifier
Per X.509 spec in 4.2.1.1 section, the structure of Authority Key Identifier Extension is: AuthorityKeyIdentifier ::= SEQUENCE { keyIdentifier [0] KeyIdentifier OPTIONAL, authorityCertIssuer [1] GeneralNamesOPTIONAL, authorityCertSerialNumber [2] CertificateSerialNumber OPTIONAL } KeyIdentifier ::= OCTET STRING When a certificate also provides authorityCertIssuer and authorityCertSerialNumber then the length of AuthorityKeyIdentifier SEQUENCE is likely to long form format. e.g. The example certificate demos/tunala/A-server.pem in openssl source: X509v3 Authority Key Identifier: keyid:49:FB:45:72:12:C4:CC:E1:45:A1:D3:08:9E:95:C4:2C:6D:55:3F:17 DirName:/C=NZ/L=Wellington/O=Really Irresponsible Authorisation Authority (RIAA)/OU=Cert-stamping/CN=Jackov al-Trades/emailAddress=none@fake.domain serial:00 Current parsing rule of OID_authorityKeyIdentifier only take care the short form format, it causes load certificate to modsign_keyring fail: [ 12.061147] X.509: Extension: 47 [ 12.075121] MODSIGN: Problem loading in-kernel X.509 certificate (-74) So, this patch add the parsing rule for support long form format against Authority Key Identifier. v2: - Removed comma from author's name. - Moved 'Short Form length' comment inside the if-body. - Changed the type of sub to size_t. - Use ASN1_INDEFINITE_LENGTH rather than writing 0x80 and 127. - Moved the key_len's value assignment before alter v. - Fixed the typo of octets. - Add 2 to v before entering the loop for calculate the length. - Removed the comment of check vlen. Cc: David Howells dhowe...@redhat.com Cc: Rusty Russell ru...@rustcorp.com.au Cc: Josh Boyer jwbo...@redhat.com Cc: Randy Dunlap rdun...@xenotime.net Cc: Herbert Xu herb...@gondor.apana.org.au Cc: David S. Miller da...@davemloft.net Signed-off-by: Chun-Yi Lee j...@suse.com --- crypto/asymmetric_keys/x509_cert_parser.c | 55 1 files changed, 47 insertions(+), 8 deletions(-) diff --git a/crypto/asymmetric_keys/x509_cert_parser.c b/crypto/asymmetric_keys/x509_cert_parser.c index 7fabc4c..59ab6d2 100644 --- a/crypto/asymmetric_keys/x509_cert_parser.c +++ b/crypto/asymmetric_keys/x509_cert_parser.c @@ -373,6 +373,9 @@ int rsa_extract_mpi(void *context, size_t hdrlen, return 0; } +/* The keyIdentifier in AuthorityKeyIdentifier SEQUENCE is tag(CONT,PRIM,0) */ +#define SEQ_TAG_KEYID (ASN1_CONT 6) + /* * Process certificate extensions that are used to qualify the certificate. */ @@ -407,21 +410,57 @@ int x509_process_extension(void *context, size_t hdrlen, } if (ctx-last_oid == OID_authorityKeyIdentifier) { + size_t key_len; + /* Get hold of the CA key fingerprint */ if (vlen 5) return -EBADMSG; - if (v[0] != (ASN1_SEQ | (ASN1_CONS 5)) || - v[1] != vlen - 2 || - v[2] != (ASN1_CONT 6) || - v[3] != vlen - 4) + + /* Authority Key Identifier must be a Constructed SEQUENCE */ + if (v[0] != (ASN1_SEQ | (ASN1_CONS 5))) return -EBADMSG; - v += 4; - vlen -= 4; - f = kmalloc(vlen * 2 + 1, GFP_KERNEL); + /* Authority Key Identifier is not indefinite length */ + if (unlikely(vlen == ASN1_INDEFINITE_LENGTH)) + return -EBADMSG; + + if (vlen ASN1_INDEFINITE_LENGTH) { + /* Short Form length */ + if (v[1] != vlen - 2 || + v[2] != SEQ_TAG_KEYID || + v[3] != vlen - 4) + return -EBADMSG; + + key_len = v[3]; + v += 4; + } else { + /* Long Form length */ + size_t seq_len = 0; + size_t sub = v[1] - ASN1_INDEFINITE_LENGTH; + + if (sub 2) + return -EBADMSG; + + /* calculate the length from subsequent octets */ + v += 2; + for (i = 0; i sub; i++) { + seq_len = 8; + seq_len |= v[i]; + } + + if (seq_len != vlen - 2 - sub || + v[sub] != SEQ_TAG_KEYID || + v[sub + 1] vlen - 4 - sub) + return -EBADMSG; + + key_len = v[sub + 1]; + v += (sub + 2); + } + + f = kmalloc(key_len * 2 + 1, GFP_KERNEL); if (!f) return -ENOMEM; - for (i = 0; i vlen; i++) + for (i = 0; i key_len; i