MODSIGN: Use PKCS#7 for module signatures [ver #4]
Subsystems (6)
David Howells
maintainercover MODSIGN: Use PKCS#7 for module signatures [ver #4]
Hi Rusty,
Here's a set of patches that does the following:
(1) Extracts both parts of an X.509 AuthorityKeyIdentifier (AKID) extension. We already extract the bit that can match the subjectKeyIdentifier (SKID) of the parent X.509 cert, but we currently ignore the bits that can match the issuer and serialNumber.
Looks up an X.509 cert by issuer and serialNumber if those are provided in the AKID. If the keyIdentifier is also provided, checks that the subjectKeyIdentifier of the cert found matches that also.
If no issuer and serialNumber are provided in the AKID, looks up an X.509 cert by SKID using the AKID keyIdentifier.
This allows module signing to be done with certificates that don't have an SKID by which they can be looked up.
(2) Makes use of the PKCS#7 facility to provide module signatures.
sign-file is replaced with a program that generates a PKCS#7 message that has no X.509 certs embedded and that has detached data (the module content) and adds it onto the message with magic string and descriptor.
(3) The PKCS#7 message (and matching X.509 cert) supply all the information that is needed to select the X.509 cert to be used to verify the signature by standard means (including selection of digest algorithm and public key algorithm). No kernel-specific magic values are required.
(4) Makes it possible to get sign-file to just write out a file containing the PKCS#7 signature blob. This can be used for debugging and potentially for firmware signing.
(5) Extract the function that does PKCS#7 signature verification on a blob from the module signing code and put it somewhere more general so that other things, such as firmware signing, can make use of it without depending on module config options.
Note that the revised sign-file program no longer supports the "-s <signature>" option as I'm not sure what the best way to deal with this is. Do we generate a PKCS#7 cert from the signature given, or do we get given a PKCS#7 cert? I lean towards the latter. Note that David Woodhouse is looking at making sign-file work with PKCS#11, so bringing back -s might not be necessary.
They can be found here also:
http://git.kernel.org/cgit/linux/kernel/git/dhowells/linux-fs.git/log/?h=modsign-pkcs7
and are tagged with:
modsign-pkcs7-20150515
Should these go via the security tree or your tree?
David
---
David Howells (7):
X.509: Extract both parts of the AuthorityKeyIdentifier X.509: Support X.509 lookup by Issuer+Serial form AuthorityKeyIdentifier PKCS#7: Allow detached data to be supplied for signature checking purposes
MODSIGN: Provide a utility to append a PKCS#7 signature to a module
MODSIGN: Use PKCS#7 messages as module signatures system_keyring.c doesn't need to #include module-internal.h
MODSIGN: Extract the blob PKCS#7 signature verifier from module signing
Luis R. Rodriguez (1):
sign-file: Add option to only create signature file
Makefile | 2 crypto/asymmetric_keys/Makefile | 8 - crypto/asymmetric_keys/pkcs7_trust.c | 10 - crypto/asymmetric_keys/pkcs7_verify.c | 80 ++++-- crypto/asymmetric_keys/x509_akid.asn1 | 35 ++ crypto/asymmetric_keys/x509_cert_parser.c | 142 ++++++---- crypto/asymmetric_keys/x509_parser.h | 5 crypto/asymmetric_keys/x509_public_key.c | 86 ++++-- include/crypto/pkcs7.h | 3 include/crypto/public_key.h | 4 include/keys/system_keyring.h | 5 init/Kconfig | 28 +- kernel/module_signing.c | 212 +-------------- kernel/system_keyring.c | 51 +++- scripts/Makefile | 2 scripts/sign-file | 421 ----------------------------- scripts/sign-file.c | 212 +++++++++++++++ 17 files changed, 578 insertions(+), 728 deletions(-) create mode 100644 crypto/asymmetric_keys/x509_akid.asn1 delete mode 100755 scripts/sign-file create mode 100755 scripts/sign-file.c
David Howells
maintainerPATCH 1/8 X.509: Extract both parts of the AuthorityKeyIdentifier [ver #4]
Extract both parts of the AuthorityKeyIdentifier, not just the keyIdentifier, as the second part can be used to match X.509 certificates by issuer and serialNumber.
---
crypto/asymmetric_keys/Makefile | 8 +- crypto/asymmetric_keys/pkcs7_trust.c | 4 - crypto/asymmetric_keys/pkcs7_verify.c | 12 +- crypto/asymmetric_keys/x509_akid.asn1 | 35 +++++++ crypto/asymmetric_keys/x509_cert_parser.c | 142 ++++++++++++++++++----------- crypto/asymmetric_keys/x509_parser.h | 5 + crypto/asymmetric_keys/x509_public_key.c | 8 +- 7 files changed, 145 insertions(+), 69 deletions(-) create mode 100644 crypto/asymmetric_keys/x509_akid.asn1
crypto/asymmetric_keys/Makefile +7 -1
@@ -15,15 +15,21 @@ obj-$(CONFIG_PUBLIC_KEY_ALGO_RSA) += rsa.o obj-$(CONFIG_X509_CERTIFICATE_PARSER) += x509_key_parser.o x509_key_parser-y := \ x509-asn1.o \ + x509_akid-asn1.o \ x509_rsakey-asn1.o \ x509_cert_parser.o \ x509_public_key.o -$(obj)/x509_cert_parser.o: $(obj)/x509-asn1.h $(obj)/x509_rsakey-asn1.h +$(obj)/x509_cert_parser.o: \ + $(obj)/x509-asn1.h \ + $(obj)/x509_akid-asn1.h \ + $(obj)/x509_rsakey-asn1.h $(obj)/x509-asn1.o: $(obj)/x509-asn1.c $(obj)/x509-asn1.h +$(obj)/x509_akid-asn1.o: $(obj)/x509_akid-asn1.c $(obj)/x509_akid-asn1.h $(obj)/x509_rsakey-asn1.o: $(obj)/x509_rsakey-asn1.c $(obj)/x509_rsakey-asn1.h clean-files += x509-asn1.c x509-asn1.h +clean-files += x509_akid-asn1.c x509_akid-asn1.h clean-files += x509_rsakey-asn1.c x509_rsakey-asn1.h #
crypto/asymmetric_keys/pkcs7_trust.c +2 -2
@@ -85,8 +85,8 @@ static int pkcs7_validate_trust_one(struct pkcs7_message *pkcs7,/* No match - see if the root certificate has a signer amongst the * trusted keys. */ -if (last && last->authority) { - key =x509_request_asymmetric_key (trust_keyring, last->authority, +if (last && last->akid_skid) { + key =x509_request_asymmetric_key (trust_keyring, last->akid_skid, false);if (!IS_ERR (key)) { x509 = last;
crypto/asymmetric_keys/pkcs7_verify.c +5 -7
@@ -187,11 +187,11 @@ static int pkcs7_verify_sig_chain(struct pkcs7_message *pkcs7, goto maybe_missing_crypto_in_x509;pr_debug ("- issuer %s\n" , x509->issuer); -if (x509->authority) +if (x509->akid_skid)pr_debug ("- authkeyid %*phN\n" , - x509->authority->len, x509->authority->data); + x509->akid_skid->len, x509->akid_skid->data); -if (!x509->authority || +if (!x509->akid_skid ||strcmp (x509->subject, x509->issuer) ==0 ) {/* If there's no authority certificate specified, then * the certificate must be self-signed and is the root
@@ -216,13 +216,13 @@ static int pkcs7_verify_sig_chain(struct pkcs7_message *pkcs7,* list to see if the next one is there. */ pr_debug ("- want %*phN\n" , - x509->authority->len, x509->authority->data); + x509->akid_skid->len, x509->akid_skid->data);for (p = pkcs7->certs; p; p = p->next) {if (!p->skid)continue ;pr_debug ("- cmp [%u] %*phN\n" , p->index, p->skid->len, p->skid->data); -if (asymmetric_key_id_same (p->skid, x509->authority)) +if (asymmetric_key_id_same (p->skid, x509->akid_skid)) goto found_issuer; }
@@ -338,8 +338,6 @@ int pkcs7_verify(struct pkcs7_message *pkcs7) ret =x509_get_sig_params (x509);if (ret <0 )return ret; -pr_debug ("X.509[%u] %*phN\n" , - n, x509->authority->len, x509->authority->data); }for (sinfo = pkcs7->signed_infos; sinfo; sinfo = sinfo->next) {
crypto/asymmetric_keys/x509_akid.asn1 new file +35 -0
@@ -0,0 +1,35 @@ +-- X.509 AuthorityKeyIdentifier +-- rfc5280 section 4.2.1.1 + +AuthorityKeyIdentifier ::= SEQUENCE { + keyIdentifier [0] IMPLICIT KeyIdentifier OPTIONAL, + authorityCertIssuer [1] IMPLICIT GeneralNames OPTIONAL, + authorityCertSerialNumber [2] IMPLICIT CertificateSerialNumber OPTIONAL + } + +KeyIdentifier ::= OCTET STRING ({ x509_akid_note_kid }) + +CertificateSerialNumber ::= INTEGER ({ x509_akid_note_serial }) + +GeneralNames ::= SEQUENCE OF GeneralName + +GeneralName ::= CHOICE { + otherName [0] ANY, + rfc822Name [1] IA5String, + dNSName [2] IA5String, + x400Address [3] ANY, + directoryName [4] Name ({ x509_akid_note_name }), + ediPartyName [5] ANY, + uniformResourceIdentifier [6] IA5String, + iPAddress [7] OCTET STRING, + registeredID [8] OBJECT IDENTIFIER + } + +Name ::= SEQUENCE OF RelativeDistinguishedName + +RelativeDistinguishedName ::= SET OF AttributeValueAssertion + +AttributeValueAssertion ::= SEQUENCE { + attributeType OBJECT IDENTIFIER ({ x509_note_OID }), + attributeValue ANY ({ x509_extract_name_segment }) + }
crypto/asymmetric_keys/x509_cert_parser.c +89 -53
181 lines not on this page · raw message
crypto/asymmetric_keys/x509_parser.h +3 -2
@@ -19,9 +19,10 @@ struct x509_certificate {struct public_key_signature sig;/* Signature parameters */ char *issuer;/* Name of certificate issuer */ char *subject;/* Name of certificate subject */ -struct asymmetric_key_id *id;/* Serial number + issuer */ +struct asymmetric_key_id *id;/* Issuer + Serial number */ struct asymmetric_key_id *skid;/* Subject + subjectKeyId (optional) */ -struct asymmetric_key_id *authority;/* Authority key identifier (optional) */ +struct asymmetric_key_id *akid_id;/* CA AuthKeyId matching ->id (optional) */ +struct asymmetric_key_id *akid_skid;/* CA AuthKeyId matching ->skid (optional) */ struct tm valid_from;struct tm valid_to;const void *tbs;/* Signed data */
crypto/asymmetric_keys/x509_public_key.c +4 -4
@@ -214,10 +214,10 @@ static int x509_validate_trust(struct x509_certificate *cert,if (!trust_keyring)return -EOPNOTSUPP ; -if (ca_keyid && !asymmetric_key_id_partial (cert->authority, ca_keyid)) +if (ca_keyid && !asymmetric_key_id_partial (cert->akid_skid, ca_keyid))return -EPERM ; - key =x509_request_asymmetric_key (trust_keyring, cert->authority, + key =x509_request_asymmetric_key (trust_keyring, cert->akid_skid, false);if (!IS_ERR (key)) { if (!use_builtin_keys
@@ -274,8 +274,8 @@ static int x509_key_preparse(struct key_preparsed_payload *prep) cert->pub->id_type =PKEY_ID_X509 ;/* Check the signature on the key if it appears to be self-signed */ -if (!cert->authority || -asymmetric_key_id_same (cert->skid, cert->authority)) { +if (!cert->akid_skid || +asymmetric_key_id_same (cert->skid, cert->akid_skid)) { ret =x509_check_signature (cert->pub, cert);/* self-signed */ if (ret <0 ) goto error_free_cert;
David Howells
maintainerPATCH 2/8 X.509: Support X.509 lookup by Issuer+Serial form AuthorityKeyIdentifier [ver #4]
In reply to David HowellsIf an X.509 certificate has an AuthorityKeyIdentifier extension that provides an issuer and serialNumber, then make it so that these are used in preference to the keyIdentifier field also held therein for searching for the signing certificate.
If both the issuer+serialNumber and the keyIdentifier are supplied, then the certificate is looked up by the former but the latter is checked as well. If the latter doesn't match the subjectKeyIdentifier of the parent certificate, EKEYREJECTED is returned.
This makes it possible to chain X.509 certificates based on the issuer and serialNumber fields rather than on subjectKeyIdentifier. This is necessary as we are having to deal with keys that are represented by X.509 certificates that lack a subjectKeyIdentifier.
---
crypto/asymmetric_keys/pkcs7_trust.c | 10 +++- crypto/asymmetric_keys/pkcs7_verify.c | 47 +++++++++++++---- crypto/asymmetric_keys/x509_public_key.c | 84 +++++++++++++++++++++--------- include/crypto/public_key.h | 3 + 4 files changed, 103 insertions(+), 41 deletions(-)
crypto/asymmetric_keys/pkcs7_trust.c +7 -3
@@ -54,7 +54,8 @@ static int pkcs7_validate_trust_one(struct pkcs7_message *pkcs7,/* Look to see if this certificate is present in the trusted * keys. */ - key =x509_request_asymmetric_key (trust_keyring, x509->id, + key =x509_request_asymmetric_key (trust_keyring, + x509->id, x509->skid, false);if (!IS_ERR (key)) {/* One of the X.509 certificates in the PKCS#7 message
@@ -85,8 +86,10 @@ static int pkcs7_validate_trust_one(struct pkcs7_message *pkcs7,/* No match - see if the root certificate has a signer amongst the * trusted keys. */ -if (last && last->akid_skid) { - key =x509_request_asymmetric_key (trust_keyring, last->akid_skid, +if (last && (last->akid_id || last->akid_skid)) { + key =x509_request_asymmetric_key (trust_keyring, + last->akid_id, + last->akid_skid, false);if (!IS_ERR (key)) { x509 = last;
@@ -103,6 +106,7 @@ static int pkcs7_validate_trust_one(struct pkcs7_message *pkcs7,*/ key =x509_request_asymmetric_key (trust_keyring, sinfo->signing_cert_id, +NULL , false);if (!IS_ERR (key)) { pr_devel("sinfo %u: Direct signer is key %x\n",
crypto/asymmetric_keys/pkcs7_verify.c +36 -11
74 lines not on this page · raw message
crypto/asymmetric_keys/x509_public_key.c +58 -26
128 lines not on this page · raw message
include/crypto/public_key.h +2 -1
@@ -101,7 +101,8 @@ extern int verify_signature(const struct key *key,struct asymmetric_key_id ;extern struct key *x509_request_asymmetric_key (struct key *keyring, -const struct asymmetric_key_id *kid, +const struct asymmetric_key_id *id, +const struct asymmetric_key_id *skid,bool partial);#endif /* _LINUX_PUBLIC_KEY_H */
David Howells
maintainerPATCH 3/8 PKCS#7: Allow detached data to be supplied for signature checking purposes [ver #4]
In reply to David HowellsIt is possible for a PKCS#7 message to have detached data. However, to verify the signatures on a PKCS#7 message, we have to be able to digest the data. Provide a function to supply that data. An error is given if the PKCS#7 message included embedded data.
This is used in a subsequent patch to supply the data to module signing where the signature is in the form of a PKCS#7 message with detached data, whereby the detached data is the module content that is signed.
---
crypto/asymmetric_keys/pkcs7_verify.c | 25 +++++++++++++++++++++++++ include/crypto/pkcs7.h | 3 +++ 2 files changed, 28 insertions(+)
crypto/asymmetric_keys/pkcs7_verify.c +25 -0
@@ -382,3 +382,28 @@ int pkcs7_verify(struct pkcs7_message *pkcs7)return enopkg; }EXPORT_SYMBOL_GPL (pkcs7_verify); + +/** +* pkcs7_supply_detached_data - Supply the data needed to verify a PKCS#7 message +* @pkcs7: The PKCS#7 message +* @data: The data to be verified +* @datalen: The amount of data +* +* Supply the detached data needed to verify a PKCS#7 message. Note that no +* attempt to retain/pin the data is made. That is left to the caller. The +* data will not be modified by pkcs7_verify() and will not be freed when the +* PKCS#7 message is freed. +* +* Returns -EINVAL if data is already supplied in the message, 0 otherwise. +*/ +int pkcs7_supply_detached_data (struct pkcs7_message *pkcs7, +const void *data,size_t datalen) +{ +if (pkcs7->data) { +pr_debug ("Data already supplied\n" ); +return -EINVAL ; + } + pkcs7->data = data; + pkcs7->data_len = datalen; +return 0 ; +}
include/crypto/pkcs7.h +3 -0
@@ -34,3 +34,6 @@ extern int pkcs7_validate_trust(struct pkcs7_message *pkcs7,* pkcs7_verify.c */ extern int pkcs7_verify (struct pkcs7_message *pkcs7); + +extern int pkcs7_supply_detached_data (struct pkcs7_message *pkcs7, +const void *data,size_t datalen);
David Howells
maintainerPATCH 4/8 MODSIGN: Provide a utility to append a PKCS#7 signature to a module [ver #4]
In reply to David HowellsProvide a utility that:
(1) Digests a module using the specified hash algorithm (typically sha256).
[The digest can be dumped into a file by passing the '-d' flag]
(2) Generates a PKCS#7 message that:
(a) Has detached data (ie. the module content).
(b) Is signed with the specified private key.
(c) Refers to the specified X.509 certificate.
(d) Has an empty X.509 certificate list.
[The PKCS#7 message can be dumped into a file by passing the '-p' flag]
(3) Generates a signed module by concatenating the old module, the PKCS#7 message, a descriptor and a magic string. The descriptor contains the size of the PKCS#7 message and indicates the id_type as PKEY_ID_PKCS7.
(4) Either writes the signed module to the specified destination or renames it over the source module.
This allows module signing to reuse the PKCS#7 handling code that was added for PE file parsing for signed kexec.
Note that the utility is written in C and must be linked against the OpenSSL crypto library.
Note further that I have temporarily dropped support for handling externally created signatures until we can work out the best way to do those. Hopefully, whoever creates the signature can give me a PKCS#7 certificate.
---
include/crypto/public_key.h | 1 scripts/sign-file.c | 205 +++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 206 insertions(+) create mode 100755 scripts/sign-file.c
include/crypto/public_key.h +1 -0
@@ -33,6 +33,7 @@ extern const struct public_key_algorithm *pkey_algo[PKEY_ALGO__LAST];enum pkey_id_type {PKEY_ID_PGP ,/* OpenPGP generated key ID */ PKEY_ID_X509 ,/* X.509 arbitrary subjectKeyIdentifier */ +PKEY_ID_PKCS7 ,/* Signature in PKCS#7 message */ PKEY_ID_TYPE__LAST };
scripts/sign-file.c new file +205 -0
205 lines not on this page · raw message
Re: [PATCH 4/8] MODSIGN: Provide a utility to append a PKCS#7 signature to a module [ver #4]
Quoted 49 lines · David Howells
Provide a utility that:
(1) Digests a module using the specified hash algorithm (typically sha256).
[The digest can be dumped into a file by passing the '-d' flag]
(2) Generates a PKCS#7 message that:
(a) Has detached data (ie. the module content).
(b) Is signed with the specified private key.
(c) Refers to the specified X.509 certificate.
(d) Has an empty X.509 certificate list.
[The PKCS#7 message can be dumped into a file by passing the '-p' flag]
(3) Generates a signed module by concatenating the old module, the PKCS#7 message, a descriptor and a magic string. The descriptor contains the size of the PKCS#7 message and indicates the
id_typeasPKEY_ID_PKCS7.(4) Either writes the signed module to the specified destination or renames it over the source module.
This allows module signing to reuse the PKCS#7 handling code that was added for PE file parsing for signed kexec.
Note that the utility is written in C and must be linked against the OpenSSL crypto library.
Note further that I have temporarily dropped support for handling externally created signatures until we can work out the best way to do those. Hopefully, whoever creates the signature can give me a PKCS#7 certificate.
Signed-off-by David Howells <[email protected]>Tested-by Vivek Goyal <[email protected]>---
include/crypto/public_key.h | 1 scripts/sign-file.c | 205 +++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 206 insertions(+)create mode 100755
scripts/sign-file.cinclude/crypto/public_key.h +0
-0
include/crypto/public_key.h extern const struct public_key_algorithm *pkey_algo[PKEY_ALGO__LAST]; · line 39
Quoted 7 lines
include/crypto/public_key.h +1
-0@@ -33,6 +33,7 @@ extern const struct public_key_algorithm *pkey_algo[PKEY_ALGO__LAST];enum pkey_id_type {PKEY_ID_PGP ,/* OpenPGP generated key ID */ PKEY_ID_X509 ,/* X.509 arbitrary subjectKeyIdentifier */ +PKEY_ID_PKCS7 ,/* Signature in PKCS#7 message */ PKEY_ID_TYPE__LAST };
I don't understand these comments. "OpenPGP generated key ID" refers to the name of a key. "X.509 arbitrary subjectKeyIdentifier" also refers to a name of a key. "Signature in PKCS#7 message" refers to a signature style. This seems inconsistent.
Also, I think we're really going to want signatures that specify their purpose, e.g. "module named xyz" or "firmware file named abc" or "kexec image". Let's get this right the first time rather than needing yet another type in the very near future.
Finally, why are we using PKCS#7 for this? Can't everything except kexec images use raw signatures in some trivial non-ASN.1-ified format?
A raw signature can reference a UEFI-sourced key just fine.
It could be as simple as:
4 bytes of signature type
(length of pubkey identifier, pubkey identifier) 4 bytes of purpose
(length of purpose-specific data, purpose-specific data)
The signature would be over the purpose, length of purpose-specific data, purpose-specific data, and the hash of the module.
Purpose could be PURPOSE_MODULE, PURPOSE_FIRMWARE, etc. PURPOSE_FIRMWARE's purpose-specific data could be the firmware file name.
One of the signature types could be SIGTYPE_RSA_SHA256. For that sigtype, the pubkey identifier would be the subjectPublicKeyInfo and the signature would be whatever the simplest standard encoding of an RSA signature is (probably just the raw data).
Generating and parsing this would be dead simple, and it solves a problem that needs solving (the purpose field).
kexec images probably need PKCS#7 support for Authenticode. Ick. That could be completely separate, though.
--Andy
David Howells
maintainerRe: [PATCH 4/8] MODSIGN: Provide a utility to append a PKCS#7 signature to a module [ver #4]
Quoted 11 lines · Andy Lutomirski
include/crypto/public_key.h extern const struct public_key_algorithm *pkey_algo[PKEY_ALGO__LAST]; · line 38
Quoted 7 lines
enum pkey_id_type { PKEY_ID_PGP, /* OpenPGP generated key ID */ PKEY_ID_X509, /* X.509 arbitrary subjectKeyIdentifier */include/crypto/public_key.h +1
-0+PKEY_ID_PKCS7 ,/* Signature in PKCS#7 message */ PKEY_ID_TYPE__LAST };I don't understand these comments. "OpenPGP generated key ID" refers to the name of a key. "X.509 arbitrary subjectKeyIdentifier" also refers to a name of a key.
OpenPGP was how we did things originally. We then switched to X.509 because we had to take account of UEFI. These values are implicit parts of the kernel ABI.
Quoted 2 lines
"Signature in PKCS#7 message" refers to a signature style. This seems inconsistent.
Not precisely. The format of the descriptor is immutable given the particular magic number. You set the ID type to that and all the other fields bar one to zero and you put the signature and all the metadata in the PKCS#7 blob which you place directly prior to the descriptor (the length of the blob is the one thing you do need to specify). Effectively, it's an override.
Quoted 4 lines
Also, I think we're really going to want signatures that specify their purpose, e.g. "module named xyz" or "firmware file named abc" or "kexec image". Let's get this right the first time rather than needing yet another type in the very near future.
If this is so, then this _must_ also apply to your hash list idea.
Quoted 3 lines
Finally, why are we using PKCS#7 for this? Can't everything except kexec images use raw signatures in some trivial non-ASN.1-ified format? A raw signature can reference a UEFI-sourced key just fine.
We have PKCS#7 already in the kernel. It's a standard. We can add attributes of our own devising to extend it if necessary (say your typing idea referenced above).
Quoted 6 lines
It could be as simple as:
4 bytes of signature type
(length of pubkey identifier, pubkey identifier) 4 bytes of purpose
(length of purpose-specific data, purpose-specific data)
Let's not create yet another unextendable non-standard standard.
David
Re: [PATCH 4/8] MODSIGN: Provide a utility to append a PKCS#7 signature to a module [ver #4]
Quoted 18 lines · David Howells
Quoted 11 lines · Andy Lutomirski
Quoted 7 lines
enum
pkey_id_type{PKEY_ID_PGP, /* OpenPGP generated key ID */ PKEY_ID_X509, /* X.509 arbitrary subjectKeyIdentifier */ + PKEY_ID_PKCS7, /* Signature in PKCS#7 message */
PKEY_ID_TYPE__LAST
};I don't understand these comments. "OpenPGP generated key ID" refers to the name of a key. "X.509 arbitrary subjectKeyIdentifier" also refers to a name of a key.
OpenPGP was how we did things originally. We then switched to X.509 because we had to take account of UEFI. These values are implicit parts of the kernel ABI.
Quoted 8 lines
Quoted 2 lines
"Signature in PKCS#7 message" refers to a signature style. This seems inconsistent.
Not precisely. The format of the descriptor is immutable given the particular magic number. You set the ID type to that and all the other fields bar one to zero and you put the signature and all the metadata in the PKCS#7 blob which you place directly prior to the descriptor (the length of the blob is the one thing you do need to specify). Effectively, it's an override.
Is there a document anywhere in the kernel tree that defines the actual format? I suspect that this will confuse most people who read the code right now.
Quoted 7 lines
Quoted 5 lines
Also, I think we're really going to want signatures that specify their purpose, e.g. "module named xyz" or "firmware file named abc" or "kexec image". Let's get this right the first time rather than needing yet another type in the very near future.
If this is so, then this _must_ also apply to your hash list idea.
Definitely.
Quoted 9 lines
Quoted 4 lines
Finally, why are we using PKCS#7 for this? Can't everything except kexec images use raw signatures in some trivial non-ASN.1-ified format? A raw signature can reference a UEFI-sourced key just fine.
We have PKCS#7 already in the kernel. It's a standard. We can add attributes of our own devising to extend it if necessary (say your typing idea referenced above).
Quoted 8 lines
Quoted 6 lines
It could be as simple as:
4 bytes of signature type
(length of pubkey identifier, pubkey identifier) 4 bytes of purpose
(length of purpose-specific data, purpose-specific data)Let's not create yet another unextendable non-standard standard.
It doesn't really have to be a standard at all.
Actually, I don't see why we are even trying to make the module signature format compatible across kernel versions. The module payload is completely incompatible across kernel versions already. Firmware is a different story, of course.
Also, I'll personally take some simple ad-hoc thing over PKCS#7 any day. I've tried reading the PKCS stuff. 90% is completely inapplicable to anything the kernel (or the Internet in general, for that matter) will ever do, and the other 10% is very poorly designed.
Heck, moving to NaCl format might be a good idea except for the NIST/FIPS compliance part.
--Andy
David Howells
maintainerPATCH 5/8 MODSIGN: Use PKCS#7 messages as module signatures [ver #4]
In reply to David HowellsMove to using PKCS#7 messages as module signatures because:
(1) We have to be able to support the use of X.509 certificates that don't have a subjKeyId set. We're currently relying on this to look up the X.509 certificate in the trusted keyring list.
(2) PKCS#7 message signed information blocks have a field that supplies the data required to match with the X.509 certificate that signed it.
(3) The PKCS#7 certificate carries fields that specify the digest algorithm used to generate the signature in a standardised way and the X.509 certificates specify the public key algorithm in a standardised way - so we don't need our own methods of specifying these.
(4) We now have PKCS#7 message support in the kernel for signed kexec purposes and we can make use of this.
To make this work, the old sign-file script has been replaced with a program that needs compiling in a previous patch. The rules to build it are added here.
---
Makefile | 2 init/Kconfig | 1 kernel/module_signing.c | 220 +++++-------------------- scripts/Makefile | 2 scripts/sign-file | 421 ----------------------------------------------- 5 files changed, 48 insertions(+), 598 deletions(-) delete mode 100755 scripts/sign-file
Makefile +1 -1
@@ -875,7 +875,7 @@ ifdef CONFIG_MODULE_SIG_ALL MODSECKEY = ./signing_key.priv MODPUBKEY = ./signing_key.x509 export MODPUBKEY -mod_sign_cmd = perl $(srctree)/scripts/sign-file $(CONFIG_MODULE_SIG_HASH) $(MODSECKEY) $(MODPUBKEY) +mod_sign_cmd = scripts/sign-file $(CONFIG_MODULE_SIG_HASH) $(MODSECKEY) $(MODPUBKEY) else mod_sign_cmd = true endif
init/Kconfig +1 -0
@@ -1875,6 +1875,7 @@ config MODULE_SIG select ASN1 select OID_REGISTRY select X509_CERTIFICATE_PARSER + select PKCS7_MESSAGE_PARSER help Check modules for valid signatures upon load: the signature is simply appended to the module. For more information see
kernel/module_signing.c +44 -176
269 lines not on this page · raw message
scripts/Makefile +2 -0
@@ -16,9 +16,11 @@ hostprogs-$(CONFIG_VT) += conmakehash hostprogs-$(BUILD_C_RECORDMCOUNT) += recordmcount hostprogs-$(CONFIG_BUILDTIME_EXTABLE_SORT) += sortextable hostprogs-$(CONFIG_ASN1) += asn1_compiler +hostprogs-$(CONFIG_MODULE_SIG) += sign-file HOSTCFLAGS_sortextable.o = -I$(srctree)/tools/include HOSTCFLAGS_asn1_compiler.o = -I$(srctree)/include +HOSTLOADLIBES_sign-file = -lcrypto always := $(hostprogs-y) $(hostprogs-m)
scripts/sign-file deleted +0 -421
421 lines not on this page · raw message
David Howells
maintainerPATCH 6/8 sign-file: Add option to only create signature file [ver #4]
In reply to David HowellsFrom: Luis R. Rodriguez <[email protected]>
Make the -d option (which currently isn't actually wired to anything) write out the PKCS#7 message as per the -p option and then exit without either modifying the source or writing out a compound file of the source, signature and metadata.
This will be useful when firmware signature support is added upstream as firmware will be left intact, and we'll only require the signature file. The descriptor is implicit by file extension and the file's own size.
---
scripts/sign-file.c | 13 ++++++++++--- 1 file changed, 10 insertions(+), 3 deletions(-)
scripts/sign-file.c +10 -3
@@ -86,13 +86,14 @@ int main(int argc, char **argv)char *hash_algo =NULL ;char *private_key_name, *x509_name, *module_name, *dest_name;bool save_pkcs7 = false, replace_orig; +bool sign_only = false;unsigned char buf[4096 ];unsigned long module_size, pkcs7_size;const EVP_MD *digest_algo;EVP_PKEY *private_key;PKCS7 *pkcs7;X509 *x509; -BIO *b, *bd, *bm; +BIO *b, *bd =NULL , *bm;int opt, n;ERR_load_crypto_strings ();
@@ -102,6 +103,7 @@ int main(int argc, char **argv) opt =getopt (argc, argv,"dp" );switch (opt) {case 'p' : save_pkcs7 = true;break ; +case 'd' : sign_only = true; save_pkcs7 = true;break ;case -1 :break ;default :format (); }
@@ -148,8 +150,10 @@ int main(int argc, char **argv)/* Open the destination file now so that we can shovel the module data * across as we read it. */ - bd =BIO_new_file (dest_name,"wb" ); -ERR (!bd,"%s" , dest_name); +if (!sign_only) { + bd =BIO_new_file (dest_name,"wb" ); +ERR (!bd,"%s" , dest_name); + }/* Digest the module data. */ OpenSSL_add_all_digests ();
@@ -180,6 +184,9 @@ int main(int argc, char **argv)BIO_free (b); } +if (sign_only) +return 0 ; +/* Append the marker and the PKCS#7 message to the destination file */ ERR (BIO_reset (bm) <0 ,"%s" , module_name); while ((n = BIO_read(bm, buf, sizeof(buf))),
David Howells
maintainersign-file and detached PKCS#7 firmware signatures
Hi Luis,
As David Woodhouse pointed out to me, you don't need sign-file if you're just going to create a detached PKCS#7 message as your signature. You can just use "openssl smime" directly.
The reason that sign-file is needed for module signing is that the signature is added to the module with a little bit of metadata to indicate its presence
- but if you're having detached signatures, that isn't relevant.
You can do this with two steps:
(1) Require that an X.509 certificate is made available to the kernel to provide the public key. One way to do this is to convert it to DER form and place it in the source directory as <name>.x509 when you build the kernel.
(2) Document that to produce a signature for a firmware blob, you just run
the following command:
openssl smime -sign \
-in $FIRMWARE_BLOB_NAME \
-outform DER \
-inkey $PRIVATE_KEY_FILE_IN_PEM_FORM \
-signer $X509_CERT_FILE_IN_PEM_FORM \
-nocerts \
-md $DIGEST_ALGORITHM \
>$PKCS7_MESSAGE_FILE_IN_DER_FORM
Note that if you have crypto hardware available that openssl can use, you
can do that in this command.To summarise, what you have to present to the kernel is the following:
(A) A DER-encoded X.509 certificate containing the public key.
(B) A DER-encoded PKCS#7 message containing the signatures.
(C) A binary blob that is the detached data for the PKCS#7 message.
David
Re: sign-file and detached PKCS#7 firmware signatures
Quoted 10 lines · David Howells
Hi Luis,
As David Woodhouse pointed out to me, you don't need sign-file if you're just going to create a detached PKCS#7 message as your signature. You can just use "openssl smime" directly.
The reason that sign-file is needed for module signing is that the signature is added to the module with a little bit of metadata to indicate its presence
- but if you're having detached signatures, that isn't relevant.
Quoted 6 lines
You can do this with two steps:
(1) Require that an X.509 certificate is made available to the kernel to provide the public key. One way to do this is to convert it to DER form and place it in the source directory as <name>.x509 when you build the kernel.
OK.
Quoted 10 lines
(2) Document that to produce a signature for a firmware blob, you just run
the following command: openssl smime -sign \ -in $FIRMWARE_BLOB_NAME \ -outform DER \ -inkey $PRIVATE_KEY_FILE_IN_PEM_FORM \ -signer $X509_CERT_FILE_IN_PEM_FORM \ -nocerts \ -md $DIGEST_ALGORITHM \
There's a missing -binary argument here, other than that this works fine.
Quoted 1 line
>$PKCS7_MESSAGE_FILE_IN_DER_FORM
I however cannot figure out how to use openssl to verify this signature.
Quoted 11 lines
Note that if you have crypto hardware available that openssl can use, you can do that in this command.
To summarise, what you have to present to the kernel is the following:
(A) A DER-encoded X.509 certificate containing the public key.
(B) A DER-encoded PKCS#7 message containing the signatures.
(C) A binary blob that is the detached data for the PKCS#7 message.
Will respin.
Lui
David Howells
maintainerRe: sign-file and detached PKCS#7 firmware signatures
Quoted 1 line · Luis R. Rodriguez
There's a missing -binary argument here, other than that this works fine.
Good point.
Quoted 3 lines
Quoted 1 line
>$PKCS7_MESSAGE_FILE_IN_DER_FORM
I however cannot figure out how to use openssl to verify this signature.
Something like:
openssl smime -verify \ -in $PKCS7_MESSAGE_FILE_IN_DER_FORM \ -inform DER \ -content $FIRMWARE_BLOB_NAME \ -inkey $PRIVATE_KEY_FILE_IN_PEM_FORM \ -signer $X509_CERT_FILE_IN_PEM_FORM
I would guess.
David
Re: sign-file and detached PKCS#7 firmware signatures
Quoted 12 lines · David Howells
Quoted 1 line · Luis R. Rodriguez
There's a missing -binary argument here, other than that this works fine.
Good point.
Quoted 3 lines
Quoted 1 line
>$PKCS7_MESSAGE_FILE_IN_DER_FORM
I however cannot figure out how to use openssl to verify this signature.
Something like:
Quoted 8 lines
openssl smime -verify \ -in $PKCS7_MESSAGE_FILE_IN_DER_FORM \ -inform DER \ -content $FIRMWARE_BLOB_NAME \ -inkey $PRIVATE_KEY_FILE_IN_PEM_FORM \ -signer $X509_CERT_FILE_IN_PEM_FORMI would guess.
I tried a few things and no luck with that.
Luis
David Howells
maintainerRe: sign-file and detached PKCS#7 firmware signatures
Quoted 9 lines · Luis R. Rodriguez
Quoted 9 lines
Something like:
openssl smime -verify \ -in $PKCS7_MESSAGE_FILE_IN_DER_FORM \ -inform DER \ -content $FIRMWARE_BLOB_NAME \ -inkey $PRIVATE_KEY_FILE_IN_PEM_FORM \ -signer $X509_CERT_FILE_IN_PEM_FORM
Quoted 3 lines
Quoted 1 line
I would guess.
I tried a few things and no luck with that.
Try this:
openssl smime -verify \ -in $PKCS7_MESSAGE_FILE_IN_DER_FORM \ -inform DER \ -certfile $X509_CERT_FILE_IN_PEM_FORM \ -content $FIRMWARE_BLOB_NAME \ -binary \ -noverify \ >/dev/null
Seems using -signer with -verify isn't a good idea as -signer refers to an output file during verification just for the surprise factor.
David
Re: sign-file and detached PKCS#7 firmware signatures
Quoted 17 lines · David Howells
Quoted 9 lines · Luis R. Rodriguez
Quoted 9 lines
Something like:
openssl smime -verify \ -in $PKCS7_MESSAGE_FILE_IN_DER_FORM \ -inform DER \ -content $FIRMWARE_BLOB_NAME \ -inkey $PRIVATE_KEY_FILE_IN_PEM_FORM \ -signer $X509_CERT_FILE_IN_PEM_FORMQuoted 3 lines
Quoted 1 line
I would guess.
I tried a few things and no luck with that.
Try this:
Quoted 8 lines
openssl smime -verify \ -in $PKCS7_MESSAGE_FILE_IN_DER_FORM \ -inform DER \ -certfile $X509_CERT_FILE_IN_PEM_FORM \ -content $FIRMWARE_BLOB_NAME \ -binary \ -noverify \ >/dev/null
Neat ok yeah this works thanks, I'll throw this in the docs too with the change to use -out /dev/null.
Luis
Re: sign-file and detached PKCS#7 firmware signatures
In reply to David HowellsI'll also mention:
---
The $DIGEST_ALGORITHM needs to be supported on the running kernel and can differ from CONFIG_MODULE_SIG_HASH.
---
As I do no think that is quite obvious to a system integrator at first.
Luis
David Howells
maintainerRe: sign-file and detached PKCS#7 firmware signatures
Quoted 8 lines · Luis R. Rodriguez
I'll also mention:
---
The $DIGEST_ALGORITHM needs to be supported on the running kernel and can differ fromCONFIG_MODULE_SIG_HASH.
---As I do no think that is quite obvious to a system integrator at first.
Actually, this isn't necessarily so for the firmware.
It *is* for the module signing, but you can always load the module to give you the digest algorithm (or public key algorithm) for the firmware.
Though you would still have to be careful with firmware loaded during the initramfs phase.
David
Re: sign-file and detached PKCS#7 firmware signatures
Quoted 4 lines · David Howells
Quoted 2 lines · Luis R. Rodriguez
I'll also mention:
Quoted 8 lines
Quoted 6 lines
---
The $DIGEST_ALGORITHM needs to be supported on the running kernel and can differ fromCONFIG_MODULE_SIG_HASH.
---As I do no think that is quite obvious to a system integrator at first.
Actually, this isn't necessarily so for the firmware.
Sorry by "needs to be supported on the running kernel" I meant "=y" or "=m".
Quoted 2 lines
It *is* for the module signing, but you can always load the module to give you the digest algorithm (or public key algorithm) for the firmware.
Sure.
Quoted 2 lines
Though you would still have to be careful with firmware loaded during the initramfs phase.
Make sense, how about:
---
The $DIGEST_ALGORITHM needs to be enabled as built-in (=y) or modular (=m) in the running kernel and can differ from CONFIG_MODULE_SIG_HASH. If you are enabling the $DIGEST_ALGORITHM as a module take care to ensure that this module will also be present on the initramfs used as some modules within the initramfs may need it if using the firmware_class APIs and firmware signing has been enabled.
---
Luis
David Howells
maintainerRe: sign-file and detached PKCS#7 firmware signatures
Quoted 11 lines · Luis R. Rodriguez
Quoted 2 lines
Though you would still have to be careful with firmware loaded during the initramfs phase.
Make sense, how about:
---
The $DIGEST_ALGORITHM needs to be enabled as built-in (=y) or modular (=m) in the running kernel and can differ fromCONFIG_MODULE_SIG_HASH. If you are enabling the $DIGEST_ALGORITHM as a module take care to ensure that this module will also be present on the initramfs used as some modules within the initramfs may need it if using the
Some firmware signatures, not modules.
Quoted 2 lines
firmware_classAPIs and firmware signing has been enabled.
---
David
David Howells
maintainerPATCH 7/8 system_keyring.c doesn't need to #include module-internal.h [ver #4]
In reply to David Howellssystem_keyring.c doesn't need to #include module-internal.h as it doesn't use the one thing that exports. Remove the inclusion.
---
kernel/system_keyring.c | 1 - 1 file changed, 1 deletion(-)
kernel/system_keyring.c +0 -1
@@ -16,7 +16,6 @@#include <linux/err.h> #include <keys/asymmetric-type.h> #include <keys/system_keyring.h> -#include "module-internal.h" struct key *system_trusted_keyring;EXPORT_SYMBOL_GPL (system_trusted_keyring);
David Howells
maintainerPATCH 8/8 MODSIGN: Extract the blob PKCS#7 signature verifier from module signing [ver #4]
In reply to David HowellsExtract the function that drives the PKCS#7 signature verification given a data blob and a PKCS#7 blob out from the module signing code and lump it with the system keyring code as it's generic. This makes it independent of module config options and opens it to use by the firmware loader.
---
include/keys/system_keyring.h | 5 ++++ init/Kconfig | 29 ++++++++++++++++-------- kernel/module_signing.c | 44 +----------------------------------- kernel/system_keyring.c | 50 +++++++++++++++++++++++++++++++++++++++++ 4 files changed, 75 insertions(+), 53 deletions(-)
include/keys/system_keyring.h +5 -0
@@ -28,4 +28,9 @@ static inline struct key *get_system_trusted_keyring(void) }#endif +#ifdef CONFIG_SYSTEM_DATA_VERIFICATION +extern int system_verify_data (const void *data,unsigned long len, +const void *raw_pkcs7,size_t pkcs7_len); +#endif +#endif /* _KEYS_SYSTEM_KEYRING_H */
init/Kconfig +19 -10
@@ -1758,6 +1758,24 @@ config SYSTEM_TRUSTED_KEYRING Keys in this keyring are used by module signature checking. +config SYSTEM_DATA_VERIFICATION + def_bool n + select SYSTEM_TRUSTED_KEYRING + select KEYS + select CRYPTO + select ASYMMETRIC_KEY_TYPE + select ASYMMETRIC_PUBLIC_KEY_SUBTYPE + select PUBLIC_KEY_ALGO_RSA + select ASN1 + select OID_REGISTRY + select X509_CERTIFICATE_PARSER + select PKCS7_MESSAGE_PARSER + help + Provide PKCS#7 message verification using the contents of the system + trusted keyring to provide public keys. This then can be used for + module verification, kexec image verification and firmware blob + verification. + config PROFILING bool "Profiling support" help
@@ -1866,16 +1884,7 @@ config MODULE_SRCVERSION_ALL config MODULE_SIG bool "Module signature verification" depends on MODULES - select SYSTEM_TRUSTED_KEYRING - select KEYS - select CRYPTO - select ASYMMETRIC_KEY_TYPE - select ASYMMETRIC_PUBLIC_KEY_SUBTYPE - select PUBLIC_KEY_ALGO_RSA - select ASN1 - select OID_REGISTRY - select X509_CERTIFICATE_PARSER - select PKCS7_MESSAGE_PARSER + select SYSTEM_DATA_VERIFICATION help Check modules for valid signatures upon load: the signature is simply appended to the module. For more information see
kernel/module_signing.c +1 -43
62 lines not on this page · raw message
kernel/system_keyring.c +50 -0
59 lines not on this page · raw message
David Woodhouse
maintainerQuoted 3 lines · David Howells
Note that David Woodhouse is looking at making sign-file work with PKCS#11, so bringing back -s might not be necessary.
I actually already *had* it working with PKCS#11, at
http://git.infradead.org/users/dwmw2/modsign-pkcs11.git
Then you went and rewrote it in C, so I'm still refactoring it. WIP at
http://git.infradead.org/users/dwmw2/modsign-pkcs11-c.git just needs me to add the ENGINE_by_id("pkcs11")... bits to scripts/sign-file.c.
I'm also vacillating about whether to allow an external *cert* to be specified separately from the key. Do we...
1. Just require the X.509 DER cert in $(topdir)/signing_key.x509,
2. Automatically extract it from $CONFIG_MODULE_SIG_EXTERNAL_KEY which shall be a file (or PKCS#11 URI) containing *both* key and cert, or
3. Add a separate CONFIG_MODULE_SIG_EXTERNAL_CERT option.
I'm probably inclined towards #2. I'll need to script something to automatically extract the key from a PEM file or PKCS#11 and drop it in DER form in $(topdir)/signing_key.x509 where needed. Using basically the same make rules we already *have* for creating a new key+cert on demand anyway.
Signature · 2 lines
David Woodhouse Open Source Technology Centre [email protected] Intel Corporation
PATCH 1/4 modsign: Abort modules_install when signing fails
In reply to David Howells--- scripts/Makefile.modinst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
scripts/Makefile.modinst +1 -1
@@ -22,7 +22,7 @@ quiet_cmd_modules_install = INSTALL $@ mkdir -p $(2) ; \ cp $@ $(2) ; \ $(mod_strip_cmd) $(2)/$(notdir $@) ; \ - $(mod_sign_cmd) $(2)/$(notdir $@) $(patsubst %,|| true,$(KBUILD_EXTMOD)) ; \ + $(mod_sign_cmd) $(2)/$(notdir $@) $(patsubst %,|| true,$(KBUILD_EXTMOD)) && \ $(mod_compress_cmd) $(2)/$(notdir $@) # Modules built outside the kernel source tree go into extra by default
Signature · 7 lines
2.4.0 -- David Woodhouse Open Source Technology Centre [email protected] Intel Corporation
Re: [PATCH 1/4] modsign: Abort modules_install when signing fails
Quoted 1 line · David Woodhouse
Signed-off-by David Woodhouse <[email protected]>
I assume the patch descriptions will be added before being upstreamed.
Quoted 9 lines
--- scripts/Makefile.modinst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)scripts/Makefile.modinst +0
-0
scripts/Makefile.modinst quiet_cmd_modules_install = INSTALL $@ · line 26
Quoted 6 lines
scripts/Makefile.modinst +1
-1@@ -22,7 +22,7 @@ quiet_cmd_modules_install = INSTALL $@ mkdir -p $(2) ; \ cp $@ $(2) ; \ $(mod_strip_cmd) $(2)/$(notdir $@) ; \ - $(mod_sign_cmd) $(2)/$(notdir $@) $(patsubst %,|| true,$(KBUILD_EXTMOD)) ; \ + $(mod_sign_cmd) $(2)/$(notdir $@) $(patsubst %,|| true,$(KBUILD_EXTMOD)) && \ $(mod_compress_cmd) $(2)/$(notdir $@)
With this patch, as expected the modules_install aborted on failure. Is
there any way to capture the reason for the failure? In my case,
dropping the '-j <num>' option resolved the problem.
Mimi
Quoted 1 line
scripts/Makefile.modinst +0
-0# Modules built outside the kernel source tree go into extra by default
Re: [PATCH 1/4] modsign: Abort modules_install when signing fails
Quoted 4 lines · Mimi Zohar
Quoted 1 line · David Woodhouse
Signed-off-by David Woodhouse <[email protected]>I assume the patch descriptions will be added before being upstreamed.
This patch aborts modules_install when signing fails :)
Quoted 3 lines
With this patch, as expected the
modules_installaborted on failure. Is
there any way to capture the reason for the failure? In my case,
dropping the '-j <num>' option resolved the problem.
Hm, was there no output from sign-file when this happened? Remember that with a parallel make the error which stops the build might not be the last thing it printed. Can you show the full output?
It's possible that there's a limit on the number of sessions you can have open to the hardware token, and we are exceeding it with a parallel build. I thought that pcscd was going to serialize the access and it should work properly though. I can certainly do 'make -j modules_install' with a Yubikey NEO here (although my test build only has about 20 modules).
Any better ideas on how to specify the key passphrase/PIN? Just put it in a file in the top-level directory?
Signature · 2 lines
David Woodhouse Open Source Technology Centre [email protected] Intel Corporation
Re: [PATCH 1/4] modsign: Abort modules_install when signing fails
Quoted 8 lines · David
Quoted 7 lines · Mimi Zohar
Quoted 1 line · David Woodhouse
Signed-off-by David Woodhouse <[email protected]>With this patch, as expected the
modules_installaborted on failure. Is
there any way to capture the reason for the failure? In my case,
dropping the '-j <num>' option resolved the problem.
My mistake the failure was there.
Quoted 3 lines
Hm, was there no output from sign-file when this happened? Remember that with a parallel make the error which stops the build might not be the last thing it printed. Can you show the full output?
/bin/sh: line 1: 22771 Segmentation fault (core dumped) scripts/sign-file "sha256" "pkcs11:manufacturer=piv_II;id=%01" ./signing_key.x509 /lib/modules/4.1.0-rc1-test+/kernel/net/ipv6/netfilter/ip6table_filter.ko/home/zohar/src/kernel/linux-integrity/scripts/Makefile.modinst:35: recipe for target 'net/ipv6/netfilter/ip6table_filter.ko' failed make[2]: *** [net/ipv6/netfilter/ip6table_filter.ko] Error 139
make[2]: *** Waiting for unfinished jobs..../bin/sh: line 1: 22842 Segmentation fault (core dumped) scripts/sign-file "sha256" "pkcs11:manufacturer=piv_II;id=%01" ./signing_key.x509 /lib/modules/4.1.0-rc1-test+/kernel/net/netfilter/nf_nat.ko/home/zohar/src/kernel/linux-integrity/scripts/Makefile.modinst:35: recipe for target 'net/netfilter/nf_nat.ko' failed make[2]: *** [net/netfilter/nf_nat.ko] Error 139/home/zohar/src/kernel/linux-integrity/Makefile:1123: recipe for target '_modinst_' failed
make[1]: *** [_modinst_] Error 2
make[1]: Leaving directory '/home/zohar/src/kernel/build/linux-test'
Makefile:146: recipe for target 'sub-make' failed
make: *** [sub-make] Error 2
Quoted 9 lines
It's possible that there's a limit on the number of sessions you can have open to the hardware token, and we are exceeding it with a parallel build. I thought that pcscd was going to serialize the access and it should work properly though. I can certainly do 'make -j
modules_install' with a Yubikey NEO here (although my test build only has about 20 modules).Any better ideas on how to specify the key passphrase/PIN? Just put it in a file in the top-level directory?
Define a kbuild command parameter?
Mimi
Re: [PATCH 1/4] modsign: Abort modules_install when signing fails
Quoted 8 lines · Mimi Zohar
/bin/sh: line 1: 22771 Segmentation fault (core dumped)scripts/sign-file"sha256" "pkcs11:manufacturer=piv_II;id=%01" ./signing_key.x509/lib/modules/4.1.0-rc1-test+/kernel/net/ipv6/netfilter/ip6table_filter.ko/home/zohar/src/kernel/linux-integrity/scripts/Makefile.modinst:35:
recipe for target 'net/ipv6/netfilter/ip6table_filter.ko' failed make[2]: *** [net/ipv6/netfilter/ip6table_filter.ko] Error 139
Hm, can you get a backtrace of that? It would be impressive if that were a bug in the very few lines of code we have in sign-file.c to handle the engine; I suspect it's more likely to be elsewhere in the OpenSSL/p11-kit-proxy/OpenSC/pcsc stack.
It only happens with 'make -j', yes?
Signature · 4 lines
Sent with Evolution's ActiveSync support. David Woodhouse Open Source Technology Centre [email protected] Intel Corporation
Re: [PATCH 1/4] modsign: Abort modules_install when signing fails
Quoted 10 lines · David
Quoted 8 lines · Mimi Zohar
/bin/sh: line 1: 22771 Segmentation fault (core dumped)scripts/sign-file"sha256" "pkcs11:manufacturer=piv_II;id=%01" ./signing_key.x509/lib/modules/4.1.0-rc1-test+/kernel/net/ipv6/netfilter/ip6table_filter.ko/home/zohar/src/kernel/linux-integrity/scripts/Makefile.modinst:35:
recipe for target 'net/ipv6/netfilter/ip6table_filter.ko' failed make[2]: *** [net/ipv6/netfilter/ip6table_filter.ko] Error 139
Quoted 6 lines
Hm, can you get a backtrace of that? It would be impressive if that were a bug in the very few lines of code we have in
sign-file.cto handle the engine; I suspect it's more likely to be elsewhere in the OpenSSL/p11-kit-proxy/OpenSC/pcsc stack.It only happens with 'make -j', yes?
To be exact, "-j 10".
Mimi
PATCH 2/4 modsign: Allow external signing key to be specified
In reply to David Howells--- Makefile | 2 +- init/Kconfig | 13 +++++++++++++ kernel/Makefile | 6 ++++++ 3 files changed, 20 insertions(+), 1 deletion(-)
Makefile +1 -1
@@ -872,7 +872,7 @@ INITRD_COMPRESS-$(CONFIG_RD_LZ4) := lz4 # export INITRD_COMPRESS := $(INITRD_COMPRESS-y) ifdef CONFIG_MODULE_SIG_ALL -MODSECKEY = ./signing_key.priv +MODSECKEY = $(CONFIG_MODULE_SIG_KEY) MODPUBKEY = ./signing_key.x509 export MODPUBKEY mod_sign_cmd = scripts/sign-file $(CONFIG_MODULE_SIG_HASH) $(MODSECKEY) $(MODPUBKEY)
init/Kconfig +13 -0
@@ -1954,6 +1954,19 @@ config MODULE_SIG_HASH default "sha384" if MODULE_SIG_SHA384 default "sha512" if MODULE_SIG_SHA512 +config MODULE_SIG_EXTERNAL_KEY + bool "Use external key for module signing" + depends on MODULE_SIG_ALL + help + Use an external private key for module signing. + +config MODULE_SIG_KEY + string "File name or PKCS#11 URI of module signing key" if MODULE_SIG_EXTERNAL_KEY + default "signing_key.priv" + help + Provide the file name of a private key in PEM format, or a PKCS#11 + URI according to RFC7512 to specify the key. + config MODULE_COMPRESS bool "Compress modules on installation" depends on MODULES
kernel/Makefile +6 -0
@@ -170,6 +170,11 @@ ifndef CONFIG_MODULE_SIG_HASH $(error Could not determine digest type to use from kernel config) endif +# 'make randconfig' might enable CONFIG_MODULE_SIG_EXTERNAL_KEY but will +# leave any strings at their default settings. We want to let the automatic +# key generation work in that case, which is why we check the string here +# instead of just using 'ifndef CONFIG_MODULE_SIG_EXTERNAL_KEY'. +ifeq ($(CONFIG_MODULE_SIG_KEY),"signing_key.priv") signing_key.priv signing_key.x509: x509.genkey @echo "###" @echo "### Now generating an X.509 key pair to be used for signing modules."
@@ -207,3 +212,4 @@ x509.genkey: @echo >>x509.genkey "subjectKeyIdentifier=hash" @echo >>x509.genkey "authorityKeyIdentifier=keyid" endif +endif
Signature · 5 lines
2.4.0 -- David Woodhouse Open Source Technology Centre [email protected] Intel Corporation
PATCH 3/4 modsign: Allow password to be specified for signing key
In reply to David Howells--- Documentation/module-signing.txt | 2 ++ Makefile | 1 + init/Kconfig | 6 ++++++ scripts/sign-file.c | 39 ++++++++++++++++++++++++++++++++++++++- 4 files changed, 47 insertions(+), 1 deletion(-)
Documentation/module-signing.txt +2 -0
@@ -194,6 +194,8 @@ The hash algorithm used does not have to match the one configured, but if it doesn't, you should make sure that hash algorithm is either built into the kernel or can be loaded without requiring itself. +If the private key requires a passphrase or PIN, it can be provided in the +$CONFIG_MODULE_SIG_KEY_PASSWORD environment variable. ============================ SIGNED MODULES AND STRIPPING
Makefile +1 -0
@@ -875,6 +875,7 @@ ifdef CONFIG_MODULE_SIG_ALL MODSECKEY = $(CONFIG_MODULE_SIG_KEY) MODPUBKEY = ./signing_key.x509 export MODPUBKEY +export CONFIG_MODULE_SIG_KEY_PASSWORD mod_sign_cmd = scripts/sign-file $(CONFIG_MODULE_SIG_HASH) $(MODSECKEY) $(MODPUBKEY) else mod_sign_cmd = true
init/Kconfig +6 -0
@@ -1967,6 +1967,12 @@ config MODULE_SIG_KEY Provide the file name of a private key in PEM format, or a PKCS#11 URI according to RFC7512 to specify the key. +config MODULE_SIG_KEY_PASSWORD + string "Passphrase or PIN for module signing key if needed" if MODULE_SIG_EXTERNAL_KEY + help + If a passphrase or PIN is required for the private key, provide + it here. + config MODULE_COMPRESS bool "Compress modules on installation" depends on MODULES
scripts/sign-file.c +38 -1
@@ -80,9 +80,32 @@ static void drain_openssl_errors(void) } \ }while (0 ) +static char *key_pass; + +static int pem_pw_cb (char *buf,int len,int w,void *v) +{ +int pwlen; + +if (!key_pass) +return -1 ; + + pwlen =strlen (key_pass); +if (pwlen >= len) +return -1 ; + +strcpy (buf, key_pass); + +/* If it's wrong, don't keep trying it. */ +free (key_pass); + key_pass =NULL ; + +return pwlen; +} +int main (int argc,char **argv) {struct module_signature sig_info = { .id_type =PKEY_ID_PKCS7 }; +const char *pass_env;char *hash_algo =NULL ;char *private_key_name, *x509_name, *module_name, *dest_name;bool save_pkcs7 = false, replace_orig;
@@ -96,6 +119,7 @@ int main(int argc, char **argv)BIO *b, *bd =NULL , *bm;int opt, n; +OpenSSL_add_all_algorithms ();ERR_load_crypto_strings ();ERR_clear_error ();
@@ -127,12 +151,25 @@ int main(int argc, char **argv) replace_orig = true; } + pass_env =getenv ("CONFIG_MODULE_SIG_KEY_PASSWORD" ); +if (pass_env) { +int pwlen =strlen (pass_env); + +if (pass_env[0 ] =='\"' && pass_env[pwlen -1 ] =='\"' ) { + pass_env++; + pwlen -=2 ; + } +if (pwlen) + key_pass =strndup (pass_env, pwlen); + } +/* Read the private key and the X.509 cert the PKCS#7 message * will point to. */ b =BIO_new_file (private_key_name,"rb" );ERR (!b,"%s" , private_key_name); - private_key =PEM_read_bio_PrivateKey (b,NULL ,NULL ,NULL ); + private_key =PEM_read_bio_PrivateKey (b,NULL , pem_pw_cb,NULL ); +ERR (!private_key,"%s" , private_key_name);BIO_free (b); b =BIO_new_file (x509_name,"rb" );
Signature · 5 lines
2.4.0 -- David Woodhouse Open Source Technology Centre [email protected] Intel Corporation
Re: [PATCH 3/4] modsign: Allow password to be specified for signing key
Quoted 13 lines · David Woodhouse
Signed-off-by David Woodhouse <[email protected]>--- Documentation/module-signing.txt | 2 ++ Makefile | 1 + init/Kconfig | 6 ++++++ scripts/sign-file.c | 39 ++++++++++++++++++++++++++++++++++++++- 4 files changed, 47 insertions(+), 1 deletion(-)Documentation/module-signing.txt +0
-0
Documentation/module-signing.txt The hash algorithm used does not have to match the one configured, but if it · line 198
Quoted 5 lines
Documentation/module-signing.txt +2
-0@@ -194,6 +194,8 @@ The hash algorithm used does not have to match the one configured, but if it doesn't, you should make sure that hash algorithm is either built into the kernel or can be loaded without requiring itself. +If the private key requires a passphrase or PIN, it can be provided in the +$CONFIG_MODULE_SIG_KEY_PASSWORD environment variable.
This works, but probably is not a good idea. For one, if IKCONFIG is enabled, the pin is readily visible via /proc/config.gz.
Mimi
Quoted 106 lines
Documentation/module-signing.txt +0
-0============================ SIGNED MODULES AND STRIPPINGMakefile +1
-0@@ -875,6 +875,7 @@ ifdef CONFIG_MODULE_SIG_ALL MODSECKEY = $(CONFIG_MODULE_SIG_KEY) MODPUBKEY = ./signing_key.x509 export MODPUBKEY +export CONFIG_MODULE_SIG_KEY_PASSWORD mod_sign_cmd = scripts/sign-file $(CONFIG_MODULE_SIG_HASH) $(MODSECKEY) $(MODPUBKEY) else mod_sign_cmd = trueinit/Kconfig +6
-0@@ -1967,6 +1967,12 @@ config MODULE_SIG_KEY Provide the file name of a private key in PEM format, or a PKCS#11 URI according to RFC7512 to specify the key. +config MODULE_SIG_KEY_PASSWORD + string "Passphrase or PIN for module signing key if needed" if MODULE_SIG_EXTERNAL_KEY + help + If a passphrase or PIN is required for the private key, provide + it here. + config MODULE_COMPRESS bool "Compress modules on installation" depends on MODULESscripts/sign-file.c +38
-1@@ -80,9 +80,32 @@ static void drain_openssl_errors(void) } \ }while (0 ) +static char *key_pass; + +static int pem_pw_cb (char *buf,int len,int w,void *v) +{ +int pwlen; + +if (!key_pass) +return -1 ; + + pwlen =strlen (key_pass); +if (pwlen >= len) +return -1 ; + +strcpy (buf, key_pass); + +/* If it's wrong, don't keep trying it. */ +free (key_pass); + key_pass =NULL ; + +return pwlen; +} +int main (int argc,char **argv) {struct module_signature sig_info = { .id_type =PKEY_ID_PKCS7 }; +const char *pass_env;char *hash_algo =NULL ;char *private_key_name, *x509_name, *module_name, *dest_name;bool save_pkcs7 = false, replace_orig;@@ -96,6 +119,7 @@ int main(int argc, char **argv)BIO *b, *bd =NULL , *bm;int opt, n; +OpenSSL_add_all_algorithms ();ERR_load_crypto_strings ();ERR_clear_error ();@@ -127,12 +151,25 @@ int main(int argc, char **argv) replace_orig = true; } + pass_env =getenv ("CONFIG_MODULE_SIG_KEY_PASSWORD" ); +if (pass_env) { +int pwlen =strlen (pass_env); + +if (pass_env[0 ] =='\"' && pass_env[pwlen -1 ] =='\"' ) { + pass_env++; + pwlen -=2 ; + } +if (pwlen) + key_pass =strndup (pass_env, pwlen); + } +/* Read the private key and the X.509 cert the PKCS#7 message * will point to. */ b =BIO_new_file (private_key_name,"rb" );ERR (!b,"%s" , private_key_name); - private_key =PEM_read_bio_PrivateKey (b,NULL ,NULL ,NULL ); + private_key =PEM_read_bio_PrivateKey (b,NULL , pem_pw_cb,NULL ); +ERR (!private_key,"%s" , private_key_name);BIO_free (b); b =BIO_new_file (x509_name,"rb" );Signature · 1 line
2.4.0
PATCH 4/4 modsign: Allow signing key to be PKCS#11
In reply to David HowellsThis is only the key; the corresponding *cert* still needs to be in $(topdir)/signing_key.x509
--- scripts/sign-file.c | 29 ++++++++++++++++++++++++----- 1 file changed, 24 insertions(+), 5 deletions(-)
scripts/sign-file.c +24 -5
@@ -22,6 +22,7 @@#include <openssl/pem.h> #include <openssl/pkcs7.h> #include <openssl/err.h> +#include <openssl/engine.h> struct module_signature {uint8_t algo;/* Public-key crypto algorithm [0] */
@@ -166,11 +167,29 @@ int main(int argc, char **argv)/* Read the private key and the X.509 cert the PKCS#7 message * will point to. */ - b =BIO_new_file (private_key_name,"rb" ); -ERR (!b,"%s" , private_key_name); - private_key =PEM_read_bio_PrivateKey (b,NULL , pem_pw_cb,NULL ); -ERR (!private_key,"%s" , private_key_name); -BIO_free (b); +if (!strncmp (private_key_name,"pkcs11:" ,7 )) { +ENGINE *e; + +ENGINE_load_builtin_engines (); +drain_openssl_errors (); + e =ENGINE_by_id ("pkcs11" ); +ERR (!e,"Load PKCS#11 ENGINE" ); +if (ENGINE_init (e)) +drain_openssl_errors (); +else +ERR (1 ,"ENGINE_init" ); +if (key_pass) +ERR (!ENGINE_ctrl_cmd_string (e,"PIN" , key_pass,0 ),"Set PKCS#11 PIN" ); + private_key =ENGINE_load_private_key (e, private_key_name,NULL , +NULL ); +ERR (!private_key,"%s" , private_key_name); + }else { + b =BIO_new_file (private_key_name,"rb" ); +ERR (!b,"%s" , private_key_name); + private_key =PEM_read_bio_PrivateKey (b,NULL , pem_pw_cb,NULL ); +ERR (!private_key,"%s" , private_key_name); +BIO_free (b); + } b =BIO_new_file (x509_name,"rb" );ERR (!b,"%s" , x509_name);
Signature · 5 lines
2.4.0 -- David Woodhouse Open Source Technology Centre [email protected] Intel Corporation
David Howells
maintainerRe: [PATCH 4/4] modsign: Allow signing key to be PKCS#11
You also need to update Documentation/module-signing.txt
David
Quoted 1 line · David Howells
Hi Rusty,
Hi David,
I try to stick my nose into patches which touch module.c/h: this
doesn't, so am happy for this via another tree (AFAICT doesn't even need my ack).
Thanks,
Rusty.
Quoted 89 lines
Here's a set of patches that does the following:
(1) Extracts both parts of an X.509 AuthorityKeyIdentifier (AKID) extension. We already extract the bit that can match the subjectKeyIdentifier (SKID) of the parent X.509 cert, but we currently ignore the bits that can match the issuer and serialNumber.
Looks up an X.509 cert by issuer and serialNumber if those are provided in the AKID. If the keyIdentifier is also provided, checks that the subjectKeyIdentifier of the cert found matches that also.
If no issuer and serialNumber are provided in the AKID, looks up an X.509 cert by SKID using the AKID keyIdentifier.
This allows module signing to be done with certificates that don't have an SKID by which they can be looked up.
(2) Makes use of the PKCS#7 facility to provide module signatures.
sign-file is replaced with a program that generates a PKCS#7 message that has no X.509 certs embedded and that has detached data (the module content) and adds it onto the message with magic string and descriptor.
(3) The PKCS#7 message (and matching X.509 cert) supply all the information that is needed to select the X.509 cert to be used to verify the signature by standard means (including selection of digest algorithm and public key algorithm). No kernel-specific magic values are required.
(4) Makes it possible to get sign-file to just write out a file containing the PKCS#7 signature blob. This can be used for debugging and potentially for firmware signing.
(5) Extract the function that does PKCS#7 signature verification on a blob from the module signing code and put it somewhere more general so that other things, such as firmware signing, can make use of it without depending on module config options.
Note that the revised sign-file program no longer supports the "-s <signature>" option as I'm not sure what the best way to deal with this is. Do we generate a PKCS#7 cert from the signature given, or do we get given a PKCS#7 cert? I lean towards the latter. Note that David Woodhouse is looking at making sign-file work with PKCS#11, so bringing back -s might not be necessary.
They can be found here also:
http://git.kernel.org/cgit/linux/kernel/git/dhowells/linux-fs.git/log/?h=modsign-pkcs7
and are tagged with:
modsign-pkcs7-20150515Should these go via the security tree or your tree?
David
---
David Howells (7):
X.509: Extract both parts of the AuthorityKeyIdentifier X.509: Support X.509 lookup by Issuer+Serial form AuthorityKeyIdentifier PKCS#7: Allow detached data to be supplied for signature checking purposes
MODSIGN: Provide a utility to append a PKCS#7 signature to a module
MODSIGN: Use PKCS#7 messages as module signaturessystem_keyring.cdoesn't need to #includemodule-internal.h
MODSIGN: Extract the blob PKCS#7 signature verifier from module signingLuis R. Rodriguez (1):
sign-file: Add option to only create signature fileMakefile | 2 crypto/asymmetric_keys/Makefile | 8 - crypto/asymmetric_keys/pkcs7_trust.c | 10 - crypto/asymmetric_keys/pkcs7_verify.c | 80 ++++-- crypto/asymmetric_keys/x509_akid.asn1 | 35 ++ crypto/asymmetric_keys/x509_cert_parser.c | 142 ++++++---- crypto/asymmetric_keys/x509_parser.h | 5 crypto/asymmetric_keys/x509_public_key.c | 86 ++++-- include/crypto/pkcs7.h | 3 include/crypto/public_key.h | 4 include/keys/system_keyring.h | 5 init/Kconfig | 28 +- kernel/module_signing.c | 212 +-------------- kernel/system_keyring.c | 51 +++- scripts/Makefile | 2 scripts/sign-file | 421 ----------------------------- scripts/sign-file.c | 212 +++++++++++++++ 17 files changed, 578 insertions(+), 728 deletions(-) create mode 100644 crypto/asymmetric_keys/x509_akid.asn1 delete mode 100755 scripts/sign-file create mode 100755 scripts/sign-file.c
David Woodhouse
maintainer[PATCH 9/8] modsign: Abort modules_install when signing fails
In reply to David Howells--- scripts/Makefile.modinst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
scripts/Makefile.modinst +1 -1
@@ -22,7 +22,7 @@ quiet_cmd_modules_install = INSTALL $@ mkdir -p $(2) ; \ cp $@ $(2) ; \ $(mod_strip_cmd) $(2)/$(notdir $@) ; \ - $(mod_sign_cmd) $(2)/$(notdir $@) $(patsubst %,|| true,$(KBUILD_EXTMOD)) ; \ + $(mod_sign_cmd) $(2)/$(notdir $@) $(patsubst %,|| true,$(KBUILD_EXTMOD)) && \ $(mod_compress_cmd) $(2)/$(notdir $@) # Modules built outside the kernel source tree go into extra by default
Signature · 6 lines
2.4.0 -- David Woodhouse Open Source Technology Centre [email protected] Intel Corporation
David Woodhouse
maintainer[PATCH 10/8] modsign: Allow password to be specified for signing key
In reply to David HowellsWe don't want this in the Kconfig since it might then get exposed in /proc/config.gz. So make it a parameter to Kbuild instead. This also means we don't have to jump through hoops to strip quotes from it, as we would if it was a config option.
--- Documentation/kbuild/kbuild.txt | 5 +++++ Documentation/module-signing.txt | 3 +++ scripts/sign-file.c | 27 ++++++++++++++++++++++++++- 3 files changed, 34 insertions(+), 1 deletion(-)
Documentation/kbuild/kbuild.txt +5 -0
@@ -174,6 +174,11 @@ The output directory is often set using "O=..." on the commandline. The value can be overridden in which case the default value is ignored. +KBUILD_SIGN_PIN +-------------------------------------------------- +This variable allows a passphrase or PIN to be passed to the sign-file +utility when signing kernel modules, if the private key requires such. + KBUILD_MODPOST_WARN -------------------------------------------------- KBUILD_MODPOST_WARN can be set to avoid errors in case of undefined
Documentation/module-signing.txt +3 -0
@@ -194,6 +194,9 @@ The hash algorithm used does not have to match the one configured, but if it doesn't, you should make sure that hash algorithm is either built into the kernel or can be loaded without requiring itself. +If the private key requires a passphrase or PIN, it can be provided in the +$KBUILD_SIGN_PIN environment variable. + ============================ SIGNED MODULES AND STRIPPING
scripts/sign-file.c +26 -1
@@ -80,6 +80,27 @@ static void drain_openssl_errors(void) } \ }while (0 ) +static const char *key_pass; + +static int pem_pw_cb (char *buf,int len,int w,void *v) +{ +int pwlen; + +if (!key_pass) +return -1 ; + + pwlen =strlen (key_pass); +if (pwlen >= len) +return -1 ; + +strcpy (buf, key_pass); + +/* If it's wrong, don't keep trying it. */ + key_pass =NULL ; + +return pwlen; +} +int main (int argc,char **argv) {struct module_signature sig_info = { .id_type =PKEY_ID_PKCS7 };
@@ -96,9 +117,12 @@ int main(int argc, char **argv)BIO *b, *bd =NULL , *bm;int opt, n; +OpenSSL_add_all_algorithms ();ERR_load_crypto_strings ();ERR_clear_error (); + key_pass =getenv ("KBUILD_SIGN_PIN" ); + do { opt = getopt(argc, argv, "dp"); switch (opt) {
@@ -132,7 +156,8 @@ int main(int argc, char **argv)*/ b =BIO_new_file (private_key_name,"rb" );ERR (!b,"%s" , private_key_name); - private_key =PEM_read_bio_PrivateKey (b,NULL ,NULL ,NULL ); + private_key =PEM_read_bio_PrivateKey (b,NULL , pem_pw_cb,NULL ); +ERR (!private_key,"%s" , private_key_name);BIO_free (b); b =BIO_new_file (x509_name,"rb" );
Signature · 6 lines
2.4.0 -- David Woodhouse Open Source Technology Centre [email protected] Intel Corporation
David Howells
maintainerRe: [PATCH 10/8] modsign: Allow password to be specified for signing key
Quoted 4 lines · David Woodhouse
We don't want this in the
Kconfigsince it might then get exposed in/proc/config.gz. So make it a parameter toKbuildinstead. This also means we don't have to jump through hoops to strip quotes from it, as we would if it was a config option.
Hi Mimi,
Are you okay with this?
David
Re: [PATCH 10/8] modsign: Allow password to be specified for signing key
In reply to David WoodhouseQuoted 4 lines · David Woodhouse
We don't want this in the
Kconfigsince it might then get exposed in/proc/config.gz. So make it a parameter toKbuildinstead. This also means we don't have to jump through hoops to strip quotes from it, as we would if it was a config option.
If it were on a network-less, secure sign/build server i'd say it is OK.
However, exposing your private key's password in an environment variable on a regular Linux box is a bit fishy.
cheers,
Petko
David Woodhouse
maintainerRe: [PATCH 10/8] modsign: Allow password to be specified for signing key
Quoted 10 lines · Petko Manolov
Quoted 4 lines · David Woodhouse
We don't want this in the
Kconfigsince it might then get exposed in/proc/config.gz. So make it a parameter toKbuildinstead. This also means we don't have to jump through hoops to strip quotes from it, as we would if it was a config option.If it were on a network-less, secure sign/build server i'd say it is OK.
However, exposing your private key's password in an environment variable on a regular Linux box is a bit fishy.
I don't quite understand the objection.
If you want the modules to be signed with an external key of your choice, then for the duration of the 'make modules_sign' run (or 'make modules_install if CONFIG_MODULE_SIG_ALL=y) surely the password has to be available *somehow*?
You are, of course, free to sign the modules by invoking sign-file directly. In which case you *still* need to provide it with the password for the key somehow, if there is one.
Mimi quite rightly pointed out that my original mechanism for this, a CONFIG_MODULE_SIG_KEY_PASSWORD option, was inadvertently exposing it more than was necessary.
As it is now, you *only* need it in the environment for the duration of the operations that actually *use* it.
Do you have a better suggestion?
Signature · 2 lines
David Woodhouse Open Source Technology Centre [email protected] Intel Corporation
Re: [PATCH 10/8] modsign: Allow password to be specified for signing key
Quoted 23 lines · David Woodhouse
Quoted 10 lines · Petko Manolov
Quoted 4 lines · David Woodhouse
We don't want this in the
Kconfigsince it might then get exposed in/proc/config.gz. So make it a parameter toKbuildinstead. This also means we don't have to jump through hoops to strip quotes from it, as we would if it was a config option.If it were on a network-less, secure sign/build server i'd say it is OK.
However, exposing your private key's password in an environment variable on a regular Linux box is a bit fishy.
I don't quite understand the objection.
If you want the modules to be signed with an external key of your choice, then for the duration of the 'make
modules_sign' run (or 'makemodules_installifCONFIG_MODULE_SIG_ALL=y) surely the password has to be available *somehow*?You are, of course, free to sign the modules by invoking sign-file directly. In which case you *still* need to provide it with the password for the key somehow, if there is one.
Quoted 6 lines
Mimi quite rightly pointed out that my original mechanism for this, a
CONFIG_MODULE_SIG_KEY_PASSWORDoption, was inadvertently exposing it more than was necessary.As it is now, you *only* need it in the environment for the duration of the operations that actually *use* it.
As with everything there is bad and good side to your proposal.
bad:
- password in environment variable _could_ be very dangerous;
- someone is bound to misuse this feature sooner or later;
good:
- the actual risk is mitigated as the key is very short-lived;
- the feature is going to be used by a small number of people;
- does not break automated builds, maybe;
- there is an alternative for those who want more secure approach;
Quoted 1 line
Do you have a better suggestion?
*better* is a matter of prospective. Security and convenience are at the wrong side of the spectrum relative to each other. :)
Don't get me wrong, your patch is perhaps the lesser evil. I just wanted to bring up my concerns.
cheers,
Petko
Re: [PATCH 10/8] modsign: Allow password to be specified for signing key
In reply to David WoodhouseQuoted 4 lines · David Woodhouse
We don't want this in the
Kconfigsince it might then get exposed in/proc/config.gz. So make it a parameter toKbuildinstead. This also means we don't have to jump through hoops to strip quotes from it, as we would if it was a config option.
Definitely better. (FYI, Dmitry's modsig patches from 2012 used the keyring for safely storing a password. )
Mimi
Quoted 96 lines
Signed-off-by David Woodhouse <[email protected]>--- Documentation/kbuild/kbuild.txt | 5 +++++ Documentation/module-signing.txt | 3 +++ scripts/sign-file.c | 27 ++++++++++++++++++++++++++- 3 files changed, 34 insertions(+), 1 deletion(-)Documentation/kbuild/kbuild.txt +5
-0@@ -174,6 +174,11 @@ The output directory is often set using "O=..." on the commandline. The value can be overridden in which case the default value is ignored. +KBUILD_SIGN_PIN +-------------------------------------------------- +This variable allows a passphrase or PIN to be passed to the sign-file +utility when signing kernel modules, if the private key requires such. + KBUILD_MODPOST_WARN -------------------------------------------------- KBUILD_MODPOST_WARN can be set to avoid errors in case of undefinedDocumentation/module-signing.txt +3
-0@@ -194,6 +194,9 @@ The hash algorithm used does not have to match the one configured, but if it doesn't, you should make sure that hash algorithm is either built into the kernel or can be loaded without requiring itself. +If the private key requires a passphrase or PIN, it can be provided in the +$KBUILD_SIGN_PIN environment variable. + ============================ SIGNED MODULES AND STRIPPINGscripts/sign-file.c +26
-1@@ -80,6 +80,27 @@ static void drain_openssl_errors(void) } \ }while (0 ) +static const char *key_pass; + +static int pem_pw_cb (char *buf,int len,int w,void *v) +{ +int pwlen; + +if (!key_pass) +return -1 ; + + pwlen =strlen (key_pass); +if (pwlen >= len) +return -1 ; + +strcpy (buf, key_pass); + +/* If it's wrong, don't keep trying it. */ + key_pass =NULL ; + +return pwlen; +} +int main (int argc,char **argv) {struct module_signature sig_info = { .id_type =PKEY_ID_PKCS7 };@@ -96,9 +117,12 @@ int main(int argc, char **argv)BIO *b, *bd =NULL , *bm;int opt, n; +OpenSSL_add_all_algorithms ();ERR_load_crypto_strings ();ERR_clear_error (); + key_pass =getenv ("KBUILD_SIGN_PIN" ); + do { opt = getopt(argc, argv, "dp"); switch (opt) {@@ -132,7 +156,8 @@ int main(int argc, char **argv)*/ b =BIO_new_file (private_key_name,"rb" );ERR (!b,"%s" , private_key_name); - private_key =PEM_read_bio_PrivateKey (b,NULL ,NULL ,NULL ); + private_key =PEM_read_bio_PrivateKey (b,NULL , pem_pw_cb,NULL ); +ERR (!private_key,"%s" , private_key_name);BIO_free (b); b =BIO_new_file (x509_name,"rb" );Signature · 1 line
2.4.0
David Howells
maintainerRe: [PATCH 10/8] modsign: Allow password to be specified for signing key
Quoted 2 lines · Mimi Zohar
Definitely better. (FYI, Dmitry's modsig patches from 2012 used the keyring for safely storing a password. )
Can I add that as a reviewed-by for Dave?
David
Re: [PATCH 10/8] modsign: Allow password to be specified for signing key
Quoted 4 lines · David Howells
Quoted 2 lines · Mimi Zohar
Definitely better. (FYI, Dmitry's modsig patches from 2012 used the keyring for safely storing a password. )
Without the environment variable set, there's a pop up prompt to enter the pin. A pain to have to enter for each and every kernel module, but definitely a nice option.
Quoted 1 line
Can I add that as a reviewed-by for Dave?
Sure
Mimi
David Woodhouse
maintainerRe: [PATCH 10/8] modsign: Allow password to be specified for signing key
Quoted 9 lines · Mimi Zohar
Quoted 4 lines · David Howells
Quoted 2 lines · Mimi Zohar
Definitely better. (FYI, Dmitry's modsig patches from 2012 used the keyring for safely storing a password. )
Without the environment variable set, there's a pop up prompt to enter the pin. A pain to have to enter for each and every kernel module, but definitely a nice option.
Right. In fact now that sign-file is written in C and not having to call out to /usr/bin/openssl for each signature, we *could* authenticate to the PKCS#11 token (or load the private key from the file) just once and sign all the modules in a *single* invocation.
So you'd only be asked for the password *once*.
The make rules to achieve that are somewhat non-trivial, but it was an idea we had in our minds when we settled on doing it in C rather than scripting it.
Signature · 2 lines
David Woodhouse Open Source Technology Centre [email protected] Intel Corporation
David Woodhouse
maintainer[PATCH 11/8] modsign: Allow signing key to be PKCS#11
In reply to David HowellsThis is only the key; the corresponding *cert* still needs to be in $(topdir)/signing_key.x509. And there's no way to actually use this from the build system yet.
--- scripts/sign-file.c | 29 ++++++++++++++++++++++++----- 1 file changed, 24 insertions(+), 5 deletions(-)
scripts/sign-file.c +24 -5
@@ -22,6 +22,7 @@#include <openssl/pem.h> #include <openssl/pkcs7.h> #include <openssl/err.h> +#include <openssl/engine.h> struct module_signature {uint8_t algo;/* Public-key crypto algorithm [0] */
@@ -154,11 +155,29 @@ int main(int argc, char **argv)/* Read the private key and the X.509 cert the PKCS#7 message * will point to. */ - b =BIO_new_file (private_key_name,"rb" ); -ERR (!b,"%s" , private_key_name); - private_key =PEM_read_bio_PrivateKey (b,NULL , pem_pw_cb,NULL ); -ERR (!private_key,"%s" , private_key_name); -BIO_free (b); +if (!strncmp (private_key_name,"pkcs11:" ,7 )) { +ENGINE *e; + +ENGINE_load_builtin_engines (); +drain_openssl_errors (); + e =ENGINE_by_id ("pkcs11" ); +ERR (!e,"Load PKCS#11 ENGINE" ); +if (ENGINE_init (e)) +drain_openssl_errors (); +else +ERR (1 ,"ENGINE_init" ); +if (key_pass) +ERR (!ENGINE_ctrl_cmd_string (e,"PIN" , key_pass,0 ),"Set PKCS#11 PIN" ); + private_key =ENGINE_load_private_key (e, private_key_name,NULL , +NULL ); +ERR (!private_key,"%s" , private_key_name); + }else { + b =BIO_new_file (private_key_name,"rb" ); +ERR (!b,"%s" , private_key_name); + private_key =PEM_read_bio_PrivateKey (b,NULL , pem_pw_cb,NULL ); +ERR (!private_key,"%s" , private_key_name); +BIO_free (b); + } b =BIO_new_file (x509_name,"rb" );ERR (!b,"%s" , x509_name);
Signature · 6 lines
2.4.0 -- David Woodhouse Open Source Technology Centre [email protected] Intel Corporation
David Woodhouse
maintainer[PATCH 12/8] modsign: Allow external signing key to be specified
In reply to David Howells--- Documentation/module-signing.txt | 31 ++++++++++++++++++++++++++----- Makefile | 2 +- init/Kconfig | 14 ++++++++++++++ kernel/Makefile | 5 +++++ 4 files changed, 46 insertions(+), 6 deletions(-)
Documentation/module-signing.txt +26 -5
@@ -88,6 +88,22 @@ This has a number of options available: than being a module) so that modules signed with that algorithm can have their signatures checked without causing a dependency loop. + (4) "File name or PKCS#11 URI of module signing key" (CONFIG_MODULE_SIG_KEY) + + Setting this option to something other than its default of + "signing_key.priv" will disable the autogeneration of signing keys and + allow the kernel modules to be signed with a key of your choosing. + The string provided should identify a file containing a private key + in PEM form, or — on systems where the OpenSSL ENGINE_pkcs11 is + appropriately installed — a PKCS#11 URI as defined by RFC7512. + + If the PEM file containing the private key is encrypted, or if the + PKCS#11 token requries a PIN, this can be provided at build time by + means of the KBUILD_SIGN_PIN variable. + + The corresponding X.509 certificate in DER form should still be placed + in a file named signing_key.x509 in the top-level build directory. + ======================= GENERATING SIGNING KEYS
@@ -100,8 +116,9 @@ it can be deleted or stored securely. The public key gets built into the kernel so that it can be used to check the signatures as the modules are loaded. -Under normal conditions, the kernel build will automatically generate a new -keypair using openssl if one does not exist in the files: +Under normal conditions, when CONFIG_MODULE_SIG_KEY is unchanged from its +default of "signing_key.priv", the kernel build will automatically generate +a new keypair using openssl if one does not exist in the files: signing_key.priv signing_key.x509
@@ -135,8 +152,12 @@ kernel sources tree and the openssl command. The following is an example to generate the public/private key files: openssl req -new -nodes -utf8 -sha256 -days 36500 -batch -x509 \ - -config x509.genkey -outform DER -out signing_key.x509 \ - -keyout signing_key.priv + -config x509.genkey -outform PEM -out kernel_key.pem \ + -keyout kernel_key.pem + +The full pathname for the resulting kernel_key.pem file can then be specified +in the CONFIG_MODULE_SIG_KEY option, and the certificate and key therein will +be used instead of an autogenerated keypair. =========================
@@ -181,7 +202,7 @@ To manually sign a module, use the scripts/sign-file tool available in the Linux kernel source tree. The script requires 4 arguments: 1. The hash algorithm (e.g., sha256) - 2. The private key filename + 2. The private key filename or PKCS#11 URI 3. The public key filename 4. The kernel module to be signed
Makefile +1 -1
@@ -872,7 +872,7 @@ INITRD_COMPRESS-$(CONFIG_RD_LZ4) := lz4 # export INITRD_COMPRESS := $(INITRD_COMPRESS-y) ifdef CONFIG_MODULE_SIG_ALL -MODSECKEY = ./signing_key.priv +MODSECKEY = $(CONFIG_MODULE_SIG_KEY) MODPUBKEY = ./signing_key.x509 export MODPUBKEY mod_sign_cmd = scripts/sign-file $(CONFIG_MODULE_SIG_HASH) $(MODSECKEY) $(MODPUBKEY)
init/Kconfig +14 -0
@@ -1954,6 +1954,20 @@ config MODULE_SIG_HASH default "sha384" if MODULE_SIG_SHA384 default "sha512" if MODULE_SIG_SHA512 +config MODULE_SIG_KEY + string "File name or PKCS#11 URI of module signing key" + default "signing_key.priv" + depends on MODULE_SIG + help + Provide the file name of a private key in PKCS#8 PEM format, or + a PKCS#11 URI according to RFC7512. The corresponding X.509 + certificate in DER form should be present in signing_key.x509 + in the top-level build directory. + + If this option is unchanged from its default "signing_key.priv", + then the kernel will automatically generate the private key and + certificate as described in Documentation/module-signing.txt + config MODULE_COMPRESS bool "Compress modules on installation" depends on MODULES
kernel/Makefile +5 -0
@@ -170,6 +170,10 @@ ifndef CONFIG_MODULE_SIG_HASH $(error Could not determine digest type to use from kernel config) endif +# We do it this way rather than having a boolean option for enabling an +# external private key, because 'make randconfig' might enable such a +# boolean option and we unfortunately can't make it depend on !RANDCONFIG. +ifeq ($(CONFIG_MODULE_SIG_KEY),"signing_key.priv") signing_key.priv signing_key.x509: x509.genkey @echo "###" @echo "### Now generating an X.509 key pair to be used for signing modules."
@@ -207,3 +211,4 @@ x509.genkey: @echo >>x509.genkey "subjectKeyIdentifier=hash" @echo >>x509.genkey "authorityKeyIdentifier=keyid" endif +endif
Signature · 6 lines
2.4.0 -- David Woodhouse Open Source Technology Centre [email protected] Intel Corporation
David Woodhouse
maintainer[PATCH 13/8] modsign: Extract signing cert from CONFIG_MODULE_SIG_KEY if needed
In reply to David HowellsWhere an external PEM file or PKCS#11 URI is given, we can get the cert from it for ourselves instead of making the user drop signing_key.x509 in place for us.
---
The make rules are perhaps a little more baroque than I first intended. I wonder if I really need to cope with filenames with spaces in. I note that the *.x509 handling doesn't — if I create a file named 'foo bar.x509' the build just craps out...
Documentation/module-signing.txt | 11 ++- init/Kconfig | 8 +-- kernel/Makefile | 38 +++++++++++ scripts/Makefile | 3 +- scripts/extract-cert.c | 144 +++++++++++++++++++++++++++++++++++++++ 5 files changed, 193 insertions(+), 11 deletions(-) create mode 100644 scripts/extract-cert.c
Documentation/module-signing.txt +5 -6
@@ -93,17 +93,16 @@ This has a number of options available: Setting this option to something other than its default of "signing_key.priv" will disable the autogeneration of signing keys and allow the kernel modules to be signed with a key of your choosing. - The string provided should identify a file containing a private key - in PEM form, or — on systems where the OpenSSL ENGINE_pkcs11 is - appropriately installed — a PKCS#11 URI as defined by RFC7512. + The string provided should identify a file containing both a private + key and its corresponding X.509 certificate in PEM form, or — on + systems where the OpenSSL ENGINE_pkcs11 is functional — a PKCS#11 URI + as defined by RFC7512. In the latter case, the PKCS#11 URI should + reference both a certificate and a private key. If the PEM file containing the private key is encrypted, or if the PKCS#11 token requries a PIN, this can be provided at build time by means of the KBUILD_SIGN_PIN variable. - The corresponding X.509 certificate in DER form should still be placed - in a file named signing_key.x509 in the top-level build directory. - ======================= GENERATING SIGNING KEYS
init/Kconfig +4 -4
@@ -1959,10 +1959,10 @@ config MODULE_SIG_KEY default "signing_key.priv" depends on MODULE_SIG help - Provide the file name of a private key in PKCS#8 PEM format, or - a PKCS#11 URI according to RFC7512. The corresponding X.509 - certificate in DER form should be present in signing_key.x509 - in the top-level build directory. + Provide the file name of a private key/certificate in PEM format, + or a PKCS#11 URI according to RFC7512. The file should contain, or + the URI should identify, both the certificate and its corresponding + private key. If this option is unchanged from its default "signing_key.priv", then the kernel will automatically generate the private key and
kernel/Makefile +38 -0
@@ -210,5 +210,43 @@ x509.genkey: @echo >>x509.genkey "keyUsage=digitalSignature" @echo >>x509.genkey "subjectKeyIdentifier=hash" @echo >>x509.genkey "authorityKeyIdentifier=keyid" +else +# For external (PKCS#11 or PEM) key, we need to obtain the certificate from +# CONFIG_MODULE_SIG_KEY automatically. +quiet_cmd_extract_der = CERT_DER $(2) + cmd_extract_der = scripts/extract-cert "$(2)" signing_key.x509 + +# CONFIG_MODULE_SIG_KEY is either a PKCS#11 URI or a filename. It is +# surrounded by quotes, and may contain spaces. To strip the quotes +# with $(patsubst) we need to turn the spaces into something else. +# And if it's a filename, those spaces need to be escaped as '\ ' in +# order to use it in dependencies or $(wildcard). +space := +space += +space_escape := %%%SPACE%%% +X509_SOURCE_temp := $(subst $(space),$(space_escape),$(CONFIG_MODULE_SIG_KEY)) +# We need this to check for absolute paths or PKCS#11 URIs. +X509_SOURCE_ONEWORD := $(patsubst "%",%,$(X509_SOURCE_temp)) +# This is the actual source filename/URI without the quotes +X509_SOURCE := $(subst $(space_escape),$(space),$(X509_SOURCE_ONEWORD)) +# This\ version\ with\ spaces\ escaped\ for\ $(wildcard)\ and\ dependencies +X509_SOURCE_ESCAPED := $(subst $(space_escape),\$(space),$(X509_SOURCE_ONEWORD)) + +ifeq ($(patsubst pkcs11:%,%,$(X509_SOURCE_ONEWORD)),$(X509_SOURCE_ONEWORD)) +# If it's a filename, depend on it. +X509_DEP := $(X509_SOURCE_ESCAPED) +ifeq ($(patsubst /%,%,$(X509_SOURCE_ONEWORD)),$(X509_SOURCE_ONEWORD)) +ifeq ($(wildcard $(X509_SOURCE_ESCAPED)),) +ifneq ($(wildcard $(srctree)/$(X509_SOURCE_ESCAPED)),) +# Non-absolute filename, found in source tree and not build tree +X509_SOURCE := $(srctree)/$(X509_SOURCE) +X509_DEP := $(srctree)/$(X509_SOURCE_ESCAPED) +endif +endif +endif +endif + +signing_key.x509: scripts/extract-cert include/config/module/sig/key.h $(X509_DEP) + $(call cmd,extract_der,$(X509_SOURCE)) endif endif
scripts/Makefile +2 -1
@@ -16,11 +16,12 @@ hostprogs-$(CONFIG_VT) += conmakehash hostprogs-$(BUILD_C_RECORDMCOUNT) += recordmcount hostprogs-$(CONFIG_BUILDTIME_EXTABLE_SORT) += sortextable hostprogs-$(CONFIG_ASN1) += asn1_compiler -hostprogs-$(CONFIG_MODULE_SIG) += sign-file +hostprogs-$(CONFIG_MODULE_SIG) += sign-file extract-cert HOSTCFLAGS_sortextable.o = -I$(srctree)/tools/include HOSTCFLAGS_asn1_compiler.o = -I$(srctree)/include HOSTLOADLIBES_sign-file = -lcrypto +HOSTLOADLIBES_extract-cert = -lcrypto always := $(hostprogs-y) $(hostprogs-m)
scripts/extract-cert.c new file +144 -0
144 lines not on this page · raw message
Signature · 6 lines
2.4.0 -- David Woodhouse Open Source Technology Centre [email protected] Intel Corporation
I'm not sure I want to get involved here, but...
Quoted 14 lines · David Howells
Hi Rusty,
Here's a set of patches that does the following:
(1) Extracts both parts of an X.509 AuthorityKeyIdentifier (AKID) extension. We already extract the bit that can match the subjectKeyIdentifier (SKID) of the parent X.509 cert, but we currently ignore the bits that can match the issuer and serialNumber.
Looks up an X.509 cert by issuer and serialNumber if those are provided in the AKID. If the keyIdentifier is also provided, checks that the subjectKeyIdentifier of the cert found matches that also.
Quoted 5 lines
If no issuer and serialNumber are provided in the AKID, looks up an X.509 cert by SKID using the AKID keyIdentifier.
This allows module signing to be done with certificates that don't have an SKID by which they can be looked up.
I think this is way more complicated than it has to be. Can't we look up certificates by their subjectPublicKeyInfo? Every public key has a subjectPublicKeyInfo, and even key types that aren't X.509 at all have something equivalent to that.
Quoted 6 lines
(2) Makes use of the PKCS#7 facility to provide module signatures.
sign-file is replaced with a program that generates a PKCS#7 message that has no X.509 certs embedded and that has detached data (the module content) and adds it onto the message with magic string and descriptor.
Why is PKCS#7 better than whatever we're using now?
Quoted 5 lines
(3) The PKCS#7 message (and matching X.509 cert) supply all the information that is needed to select the X.509 cert to be used to verify the signature by standard means (including selection of digest algorithm and public key algorithm). No kernel-specific magic values are required.
I would take kernel-specific over PKCS#7 any day. PKCS#7 is severely overcomplicated for what we're doing here.
--Andy
David Howells
maintainerQuoted 2 lines · Andy Lutomirski
I think this is way more complicated than it has to be. Can't we look up certificates by their subjectPublicKeyInfo?
I want to be able to handle an X.509 chain to a root key that we have in the kernel. X.509 certs don't chain on subjectPublicKeyInfo unless that happens to be what's in the SKID (which is a pretty indefinite standard in its own right:-( ). So we need to be able to match on the two things I made available anyway. PKCS#7 matches on one of them too, so that then just works.
Quoted 1 line
Why is PKCS#7 better than whatever we're using now?
It has a standard form[*]. It has standard ways to specify things such as the key to use and the digest to use. It can carry multiple signatures from different keys and can carry key chains (something that's more likely to be useful for kexec or firmware, admittedly). It can be generated by extant tools (though adding it onto a module needs a special tool).
[*] We can agree it's a somewhat, um, ropy standard, but it's still a
standard.
What we're using now isn't very extensible without changing the magic string or putting in an override in one of the fields.
David
Quoted 10 lines · David Howells
Quoted 2 lines · Andy Lutomirski
I think this is way more complicated than it has to be. Can't we look up certificates by their subjectPublicKeyInfo?
I want to be able to handle an X.509 chain to a root key that we have in the kernel. X.509 certs don't chain on subjectPublicKeyInfo unless that happens to be what's in the SKID (which is a pretty indefinite standard in its own right:-( ). So we need to be able to match on the two things I made available anyway. PKCS#7 matches on one of them too, so that then just works.
I see. PKCS#7 (and PKCS#6 and X.509 which it inherits from) is too dumb to identify the public key that signed a certificate, so you can't match on it. Sigh.
That being said, are you actually planning on implementing X.509 chain validation correctly? ISTM you can't really do it usefully, as we don't even know what time it is when we run this code. What's the point of accepting certificate chains if there's no meaningful validation we can do?
Quoted 8 lines
Quoted 2 lines
Why is PKCS#7 better than whatever we're using now?
It has a standard form[*]. It has standard ways to specify things such as the key to use and the digest to use. It can carry multiple signatures from different keys and can carry key chains (something that's more likely to be useful for kexec or firmware, admittedly). It can be generated by extant tools (though adding it onto a module needs a special tool).
Given how much special stuff is needed (special tool to append it, probably weird or absent certificate chain validation, etc), this seems to me to be of questionable value.
Would it make more sense to permit X.509 chains to be loaded into the keyring instead if we actually need that feature? IOW, let userspace (or early initramfs stuff) extend our keyring trust to intermediate certs that validly chain to already-trusted things? I think that a reasonable design goal would be that everything overcomplicated that's involved should be optional, and moving toward embedding PKCS#7 signatures in the modules themselves does the other direction?
--Andy
Quoted 8 lines · Andy Lutomirski
Would it make more sense to permit X.509 chains to be loaded into the keyring instead if we actually need that feature? IOW, let userspace (or early initramfs stuff) extend our keyring trust to intermediate certs that validly chain to already-trusted things? I think that a reasonable design goal would be that everything overcomplicated that's involved should be optional, and moving toward embedding PKCS#7 signatures in the modules themselves does the other direction?
This is similar to what i am doing right now - create CA hierarchy so we can have something like:
+-> KeyB
|
RootCA ---> CertA ---> CertB ---> CertC ---> KeyC
|
+-> CertA' ---> KeyA"The RootCA may be the one whose private key was used to sign the modules and all downstream certificates are either directly signed by it or one of the others. Not all of the infrastructure is in the mainline kernel, but this can easily be rectified.
Now, as Mimi pointed out this scheme is flawed and should be used with care if at all. Revoking certificates is always a PITA. Being valid for one year only adds to the fun.
Petko
Quoted 19 lines · Petko Manolov
Quoted 8 lines · Andy Lutomirski
Would it make more sense to permit X.509 chains to be loaded into the keyring instead if we actually need that feature? IOW, let userspace (or early initramfs stuff) extend our keyring trust to intermediate certs that validly chain to already-trusted things? I think that a reasonable design goal would be that everything overcomplicated that's involved should be optional, and moving toward embedding PKCS#7 signatures in the modules themselves does the other direction?
This is similar to what i am doing right now - create CA hierarchy so we can have something like:
+-> KeyB | RootCA ---> CertA ---> CertB ---> CertC ---> KeyC | +-> CertA' ---> KeyA"
Quoted 4 lines
The RootCA may be the one whose private key was used to sign the modules and all downstream certificates are either directly signed by it or one of the others. Not all of the infrastructure is in the mainline kernel, but this can easily be rectified.
Right. I guess that I can imagine some uses for this, but I don't see why those intermediate certs would be embedded with the signatures being verified as opposed to being loaded beforehand.
Quoted 5 lines
Now, as Mimi pointed out this scheme is flawed and should be used with care if at all. Revoking certificates is always a PITA. Being valid for one year only adds to the fun.
Valid for only one year is worse than that. We might be verifying the signature on our clock driver :) I think that, at best, we could reject certificates that expired before the running kernel was built.
Quoted 2 lines
Petko
Signature · 2 lines
Andy Lutomirski AMA Capital Management, LLC
Quoted 20 lines · Andy Lutomirski
Quoted 19 lines · Petko Manolov
Quoted 8 lines · Andy Lutomirski
Would it make more sense to permit X.509 chains to be loaded into the keyring instead if we actually need that feature? IOW, let userspace (or early initramfs stuff) extend our keyring trust to intermediate certs that validly chain to already-trusted things? I think that a reasonable design goal would be that everything overcomplicated that's involved should be optional, and moving toward embedding PKCS#7 signatures in the modules themselves does the other direction?
This is similar to what i am doing right now - create CA hierarchy so we can have something like:
+-> KeyB | RootCA ---> CertA ---> CertB ---> CertC ---> KeyC | +-> CertA' ---> KeyA"
Quoted 8 lines
Quoted 4 lines
The RootCA may be the one whose private key was used to sign the modules and all downstream certificates are either directly signed by it or one of the others. Not all of the infrastructure is in the mainline kernel, but this can easily be rectified.
Right. I guess that I can imagine some uses for this, but I don't see why those intermediate certs would be embedded with the signatures being verified as opposed to being loaded beforehand.
They aren't. They shouldn't.
I think module signing/verification should be simple but cryptographically sound process. Over-designing it is dumb, but i find it useful when there is compatibility (at least at key format level) with other systems, namely IMA and EVM.
Quoted 8 lines
Quoted 4 lines
Now, as Mimi pointed out this scheme is flawed and should be used with care if at all. Revoking certificates is always a PITA. Being valid for one year only adds to the fun.
Valid for only one year is worse than that. We might be verifying the signature on our clock driver :) I think that, at best, we could reject certificates that expired before the running kernel was built.
Nah, nothing as complex as that. It is so easy to play with the system clock. In the general case, and if needed, the user would either use self signed certificate or one signed by whoever the user trusts - Fedora, Debian, LF or even NSA. :)
Petko
Quoted 10 lines · Petko Manolov
Quoted 8 lines · Andy Lutomirski
Would it make more sense to permit X.509 chains to be loaded into the keyring instead if we actually need that feature? IOW, let userspace (or early initramfs stuff) extend our keyring trust to intermediate certs that validly chain to already-trusted things? I think that a reasonable design goal would be that everything overcomplicated that's involved should be optional, and moving toward embedding PKCS#7 signatures in the modules themselves does the other direction?
Quoted 8 lines
This is similar to what i am doing right now - create CA hierarchy so we can have something like:
+-> KeyB | RootCA ---> CertA ---> CertB ---> CertC ---> KeyC | +-> CertA' ---> KeyA"
How exactly do you go about uploading CertB to the kernel BTW? And could fw signing replace that functionality? Keep in mind "fw uploading" should be rebranded as "system data upload", which is one of the goals I have when extending the firware_class module.
Quoted 8 lines
The RootCA may be the one whose private key was used to sign the modules and all downstream certificates are either directly signed by it or one of the others. Not all of the infrastructure is in the mainline kernel, but this can easily be rectified.
Now, as Mimi pointed out this scheme is flawed and should be used with care if at all. Revoking certificates is always a PITA. Being valid for one year only adds to the fun.
Freedom of stupidity comes with a cost :)
Luis
Quoted 20 lines · Luis R. Rodriguez
Quoted 10 lines · Petko Manolov
Quoted 8 lines · Andy Lutomirski
Would it make more sense to permit X.509 chains to be loaded into the keyring instead if we actually need that feature? IOW, let userspace (or early initramfs stuff) extend our keyring trust to intermediate certs that validly chain to already-trusted things? I think that a reasonable design goal would be that everything overcomplicated that's involved should be optional, and moving toward embedding PKCS#7 signatures in the modules themselves does the other direction?
Quoted 8 lines
This is similar to what i am doing right now - create CA hierarchy so we can have something like:
+-> KeyB | RootCA ---> CertA ---> CertB ---> CertC ---> KeyC | +-> CertA' ---> KeyA"
Quoted 4 lines
How exactly do you go about uploading CertB to the kernel BTW? And could fw signing replace that functionality? Keep in mind "fw uploading" should be rebranded as "system data upload", which is one of the goals I have when extending the
firware_classmodule.
In PKCS#7 land, you don't. Instead you stick CertB and CertC into the PKCS#7 signature on the module signed by KeyC. Then the kernel verifies them (in theory) using the X.509/PKIX godawful verification algorithm. For fun, go search for the large number of errors in the implementation of this awful algorithm in basically every TLS implementation out there.
One option would be to add another type of verifiable thing. We can verify modules, and we should add firmware to the types of things that can be signed. We could add signing keys, too. IOW, you could ask the kernel to load a signing key with certain rights, and, if they key is validly signed by some other key that has the same rights and has a bit set saying that it can delegate those rights, then the kernel will add that signing key to the keyring.
If the general infrastructure were there, this would be very little additional code.
--Andy
Quoted 11 lines · Andy Lutomirski
One option would be to add another type of verifiable thing. We can verify modules, and we should add firmware to the types of things that can be signed. We could add signing keys, too. IOW, you could ask the kernel to load a signing key with certain rights, and, if they key is validly signed by some other key that has the same rights and has a bit set saying that it can delegate those rights, then the kernel will add that signing key to the keyring.
If the general infrastructure were there, this would be very little additional code.
I really like this idea, but I've heard of many great ideas before followed by nothing but vaporware. So is it a direct requirement to implicate blocking a change for current module signature checking strategy to a new one given the concerns you raise, or can we enable those who wish to want additional better solutions as the one you propose to opt-in to develop those solutions? I like the idea of the later given that it seems those using the current module signing infrastructure would prefer the change and enabling what you say does not seem to be a not possible based on allowing that to be advanced.
Luis
Quoted 24 lines · Luis R. Rodriguez
Quoted 11 lines · Andy Lutomirski
One option would be to add another type of verifiable thing. We can verify modules, and we should add firmware to the types of things that can be signed. We could add signing keys, too. IOW, you could ask the kernel to load a signing key with certain rights, and, if they key is validly signed by some other key that has the same rights and has a bit set saying that it can delegate those rights, then the kernel will add that signing key to the keyring.
If the general infrastructure were there, this would be very little additional code.
I really like this idea, but I've heard of many great ideas before followed by nothing but vaporware. So is it a direct requirement to implicate blocking a change for current module signature checking strategy to a new one given the concerns you raise, or can we enable those who wish to want additional better solutions as the one you propose to opt-in to develop those solutions? I like the idea of the later given that it seems those using the current module signing infrastructure would prefer the change and enabling what you say does not seem to be a not possible based on allowing that to be advanced.
Quoted 1 line
From my POV (and keep in mind that I'm not really involved in this
stuff and my POV shouldn't be treated as gospel), a firmware signature verification should have verification that the signature was intended to apply to a firmware file with the name being requested as a requirement. Everything else is nice-to-have.
Given that, I would say that merely shoving firmware files through the module verifier as-is would not be okay. There's plenty of flexibility in how you fix it, though. Doing it with PKCS#7 authenticated attributes *gag* would work, but my off-the-cuff guess is that making that work is actually harder, even on top of David's patches, than doing it from scratch. PKCS#7 is not easy to work with.
FWIW, openssl rsautl can generate raw PKCS#1 v1.5 signatures (use -pkcs, not -raw). openssl pkeyutl can do PKCS#1 v2.0 (i.e. PSS) signatures, but you'd have to write the verifier yourself. The kernel already has a v1.5 verifier that even follows the best practices that I remember. (For v2.0, there's a security proof, so an implementation of the spec is actually secure and there are no "best practices" to worry about. v1.5 is known insecure if you implement it naively.)
--Andy
Quoted 2 lines · Andy Lutomirski
Given that, I would say that merely shoving firmware files through the module verifier as-is would not be okay.
Replacing one dog and pony show for another is what is going on, what you describe and suggest seems best, and I welcome patches, it seems you know what you are talking about :)
Luis
Quoted 8 lines · Luis R. Rodriguez
Quoted 2 lines · Andy Lutomirski
Given that, I would say that merely shoving firmware files through the module verifier as-is would not be okay.
Replacing one dog and pony show for another is what is going on, what you describe and suggest seems best, and I welcome patches, it seems you know what you are talking about :)
Don't hold your breath. My plate is over-full. I'm probably a decent reviewer of crypto, though.
--Andy
Quoted 5 lines · Andy Lutomirski
Quoted 4 lines · Luis R. Rodriguez
Quoted 2 lines · Andy Lutomirski
Given that, I would say that merely shoving firmware files through the module verifier as-is would not be okay.
Quoted 7 lines
Quoted 4 lines
Replacing one dog and pony show for another is what is going on, what you describe and suggest seems best, and I welcome patches, it seems you know what you are talking about :)
Don't hold your breath. My plate is over-full. I'm probably a decent reviewer of crypto, though.
Well as good as you are in 10 years we'll have better ones. So when module signature went into the kernel the real expectation should have been:
This code looks good now but is going to be complete shit and breakable a few years from now.
Hence my first implicit and now explicit claims on dog and pony shows. Best thing we can do IMHO is to just allow us to replace stupid human code with better human code later, and eventually hopefully better AI code, and so on. Since you don't have time for a real replacement maybe what we can do is at least document / target / agree for what pipe dream we want and shoot for it with time. Hopefully folks will find time to implement it.
In the meantime should that block current dog and pony show trading? I don't think so.
Luis
Quoted 21 lines · Luis R. Rodriguez
Quoted 5 lines · Andy Lutomirski
Quoted 4 lines · Luis R. Rodriguez
Quoted 2 lines · Andy Lutomirski
Given that, I would say that merely shoving firmware files through the module verifier as-is would not be okay.
Quoted 7 lines
Quoted 4 lines
Replacing one dog and pony show for another is what is going on, what you describe and suggest seems best, and I welcome patches, it seems you know what you are talking about :)
Don't hold your breath. My plate is over-full. I'm probably a decent reviewer of crypto, though.
Well as good as you are in 10 years we'll have better ones. So when module signature went into the kernel the real expectation should have been:
This code looks good now but is going to be complete shit and breakable a few years from now.
Quoted 7 lines
Hence my first implicit and now explicit claims on dog and pony shows. Best thing we can do IMHO is to just allow us to replace stupid human code with better human code later, and eventually hopefully better AI code, and so on. Since you don't have time for a real replacement maybe what we can do is at least document / target / agree for what pipe dream we want and shoot for it with time. Hopefully folks will find time to implement it.
I disagree. I'm a firm believer in security proofs. While I'm not trained in formal crypto proofs, I can sketch out a proof of why a system that properly tags its signatures is secure against a reasonable threat model. I can also show why that proof wouldn't work for a scheme without tags, and I can demonstrate the actual weakness in a scheme without tags.
In ten years, the only reason a scheme that I say looks good would be because (a) I screwed up, (b) an underlying assumption is wrong, or
(c) the implementation is subtly wrong. In particular, it won't fail because I'm insufficiently clever.
A real professional expert would be less likely to screw up.
(For reference, I wrote an actual doctoral thesis involving crypto.)
Quoted 3 lines
In the meantime should that block current dog and pony show trading? I don't think so.
Yes, since I can demonstrate the actual weakness without tags, and crypto is notoriously hard to fix once done poorly and there's a great history of obviously-theoretically-weak systems being meaningfully attacked in the real world. See, for example, every single old SSL/TLS cipher. (And yes, the crypto community knew what was wrong in theory and how to fix it when the protocol was designed. People just didn't pay attention.)
--Andy
Quoted 24 lines · Andy Lutomirski
Quoted 8 lines · Luis R. Rodriguez
Well as good as you are in 10 years we'll have better ones. So when module signature went into the kernel the real expectation should have been:
This code looks good now but is going to be complete shit and breakable a few years from now.
Quoted 7 lines
Hence my first implicit and now explicit claims on dog and pony shows. Best thing we can do IMHO is to just allow us to replace stupid human code with better human code later, and eventually hopefully better AI code, and so on. Since you don't have time for a real replacement maybe what we can do is at least document / target / agree for what pipe dream we want and shoot for it with time. Hopefully folks will find time to implement it.
I disagree. I'm a firm believer in security proofs. While I'm not trained in formal crypto proofs, I can sketch out a proof of why a system that properly tags its signatures is secure against a reasonable threat model. I can also show why that proof wouldn't work for a scheme without tags, and I can demonstrate the actual weakness in a scheme without tags.
Quoted 8 lines
In ten years, the only reason a scheme that I say looks good would be because (a) I screwed up, (b) an underlying assumption is wrong, or
(c) the implementation is subtly wrong. In particular, it won't fail because I'm insufficiently clever.A real professional expert would be less likely to screw up.
(For reference, I wrote an actual doctoral thesis involving crypto.)
OK, I think what I mentioned still holds:
these premises must hold true for a period of time, and provided you have all information. You cannot have all the information, so the "threat model" depends on the reviewer, and the information they have access to. So, still its still a dog and pony show, at least a temporal one or one with a set of clauses.
Quoted 4 lines
Quoted 2 lines
In the meantime should that block current dog and pony show trading? I don't think so.
Yes, since I can demonstrate the actual weakness without tags,
But you don't want to do the work to provide a better replacement?
Quoted 7 lines
and
crypto is notoriously hard to fix once done poorly and there's a great history of obviously-theoretically-weak systems being meaningfully attacked in the real world. See, for example, every single old SSL/TLS cipher. (And yes, the crypto community knew what was wrong in theory and how to fix it when the protocol was designed. People just didn't pay attention.)
Its a fair argument, but still -- we have the vaporware problem.
Luis
Quoted 42 lines · Luis R. Rodriguez
Quoted 24 lines · Andy Lutomirski
Quoted 8 lines · Luis R. Rodriguez
Well as good as you are in 10 years we'll have better ones. So when module signature went into the kernel the real expectation should have been:
This code looks good now but is going to be complete shit and breakable a few years from now.
Quoted 7 lines
Hence my first implicit and now explicit claims on dog and pony shows. Best thing we can do IMHO is to just allow us to replace stupid human code with better human code later, and eventually hopefully better AI code, and so on. Since you don't have time for a real replacement maybe what we can do is at least document / target / agree for what pipe dream we want and shoot for it with time. Hopefully folks will find time to implement it.
I disagree. I'm a firm believer in security proofs. While I'm not trained in formal crypto proofs, I can sketch out a proof of why a system that properly tags its signatures is secure against a reasonable threat model. I can also show why that proof wouldn't work for a scheme without tags, and I can demonstrate the actual weakness in a scheme without tags.
Quoted 8 lines
In ten years, the only reason a scheme that I say looks good would be because (a) I screwed up, (b) an underlying assumption is wrong, or
(c) the implementation is subtly wrong. In particular, it won't fail because I'm insufficiently clever.A real professional expert would be less likely to screw up.
(For reference, I wrote an actual doctoral thesis involving crypto.)
OK, I think what I mentioned still holds:
these premises must hold true for a period of time, and provided you have all information. You cannot have all the information, so the "threat model" depends on the reviewer, and the information they have access to. So, still its still a dog and pony show, at least a temporal one or one with a set of clauses.
Quoted 6 lines
Quoted 4 lines
Quoted 2 lines
In the meantime should that block current dog and pony show trading? I don't think so.
Yes, since I can demonstrate the actual weakness without tags,
But you don't want to do the work to provide a better replacement?
Hell no. At least not until someone convinces me that I want any of this on any system I build. Thus far I'm unconvinced.
Meanwhile, the threat model seems to be that you don't want an attacker not in possession of a distro-trusted or UEFI-trusted private key to cause the kernel to load incorrect firmware into a device or incorrect regulatory data.
Without tagging the purpose of the signed file, you simply don't have a cryptographic guarantee of that. The bad guy can load something else that was signed for an entirely different purpose into the wrong device, possibly crashing it, causing buffer overflows because the format is wrong, or doing any number of other bad things.
Quoted 10 lines
Quoted 8 lines
and
crypto is notoriously hard to fix once done poorly and there's a great history of obviously-theoretically-weak systems being meaningfully attacked in the real world. See, for example, every single old SSL/TLS cipher. (And yes, the crypto community knew what was wrong in theory and how to fix it when the protocol was designed. People just didn't pay attention.)Its a fair argument, but still -- we have the vaporware problem.
If you write crypto verification code for firmware and I review it, and your code doesn't cryptographically protect it adequately, I'll say that in my review. That's all.
--Andy
David Howells
maintainerQuoted 5 lines · Andy Lutomirski
Without tagging the purpose of the signed file, you simply don't have a cryptographic guarantee of that. The bad guy can load something else that was signed for an entirely different purpose into the wrong device, possibly crashing it, causing buffer overflows because the format is wrong, or doing any number of other bad things.
One suggestion David Woodhouse made with regard to tagging is that the tag could just be added into the digest before it is signed/verified and not actually stored in the signature.
This means that if you try loading the firmware for the wrong request, the signature verification will fail.
It's an interesting approach that's simple to achieve, but it has the downside that the signature will be invalid in the mismatch situation and you can't tell whether it's because the module is being misused or the signature is just wrong. However, that might be livable with.
David
Quoted 12 lines · David Howells
Quoted 5 lines · Andy Lutomirski
Without tagging the purpose of the signed file, you simply don't have a cryptographic guarantee of that. The bad guy can load something else that was signed for an entirely different purpose into the wrong device, possibly crashing it, causing buffer overflows because the format is wrong, or doing any number of other bad things.
One suggestion David Woodhouse made with regard to tagging is that the tag could just be added into the digest before it is signed/verified and not actually stored in the signature.
Quoted 7 lines
This means that if you try loading the firmware for the wrong request, the signature verification will fail.
It's an interesting approach that's simple to achieve, but it has the downside that the signature will be invalid in the mismatch situation and you can't tell whether it's because the module is being misused or the signature is just wrong. However, that might be livable with.
With transitive trust, any key on the system keyring would be able to add keys with any tag, whether the tag is in the cert or the digest. If I trust cert A to sign keys that add kernel modules or other certs that add kernel modules, it doesn't mean that I trust that cert to also sign keys that add firmware, for example, or other keys that add firmware.
Mimi
David Howells
maintainerQuoted 2 lines · Andy Lutomirski
In PKCS#7 land, you don't. Instead you stick CertB and CertC into the PKCS#7 signature on the module signed by KeyC.
Yes, that works too.
David
David Howells
maintainerQuoted 10 lines · Luis R. Rodriguez
Quoted 8 lines
This is similar to what i am doing right now - create CA hierarchy so we can have something like:
+-> KeyB | RootCA ---> CertA ---> CertB ---> CertC ---> KeyC | +-> CertA' ---> KeyA"How exactly do you go about uploading CertB to the kernel BTW?
Assuming RootCA or CertA is present in the kernel, the idea would be to use the add_key() system call or the request_key() mechanism to add the key to the system keyring. The key in the cert would only be added to the keyring if it is trusted by a key already there.
David
Quoted 11 lines · David Howells
Quoted 9 lines · Luis R. Rodriguez
Quoted 8 lines
This is similar to what i am doing right now - create CA hierarchy so we can have something like:
+-> KeyB | RootCA ---> CertA ---> CertB ---> CertC ---> KeyC | +-> CertA' ---> KeyA"
Quoted 8 lines
Quoted 1 line
How exactly do you go about uploading CertB to the kernel BTW?
Assuming RootCA or CertA is present in the kernel, the idea would be to use the
add_key()system call or therequest_key()mechanism to add the key to the system keyring. The key in the cert would only be added to the keyring if it is trusted by a key already there.From Petko's description, the RootCA is on the system keyring, but CertA
is on a new IMA trusted CA keyring. So everything you said is true,
but on this new, yet to be upstreamed, IMA trusted CA keyring.
Mimi
Quoted 14 lines · Mimi Zohar
Quoted 13 lines · David Howells
Quoted 10 lines · Luis R. Rodriguez
Quoted 8 lines
This is similar to what i am doing right now - create CA hierarchy so we can have something like:
+-> KeyB | RootCA ---> CertA ---> CertB ---> CertC ---> KeyC | +-> CertA' ---> KeyA"How exactly do you go about uploading CertB to the kernel BTW?
Quoted 8 lines
Quoted 4 lines
Assuming RootCA or CertA is present in the kernel, the idea would be to use the
add_key()system call or therequest_key()mechanism to add the key to the system keyring. The key in the cert would only be added to the keyring if it is trusted by a key already there.From Petko's description, the RootCA is on the system keyring, but CertA is on a new IMA trusted CA keyring. So everything you said is true, but on this new, yet to be upstreamed, IMA trusted CA keyring.
I only named this intermediate keyring .ima_root_ca because this is how i use it. However, it is system-wide trusted keyring, which accepts keys that are either trusted by CAs in the .system_keyring or higher level CA is already in .ima_root_ca. For example CertC will be accepted in .ima_root_ca if CertB is already there.
The name (.ima_root_ca) is misleading and should be replaced with something that better describes it's functionality. As far as i see there is no reason this keyring not to hold the CA that verifies module's signature.
Petko
David Howells
maintainerQuoted 3 lines · Andy Lutomirski
That being said, are you actually planning on implementing X.509 chain validation correctly? ISTM you can't really do it usefully, as we don't even know what time it is when we run this code.
We can't validate certificates based on time. We've been there, tried that and patched it out again. The problem is that we can't trust the system clock until we've done NTP - and possibly not even then. A dodgy or unset system clock can lead to the system not booting, even for installation.
David