Open chaws opened 3 years ago
Feedback from the project meeting: a) hash = is the pack file timestamp a reliable thing on Windows -> investigate b) is there a more scalable alternative to embedding public vendor keys into the cpackget tool? E.g. could we have a signed archive of public keys to be downloaded (independently or as part of index.pidx?) and signed with the open-cmsis-pack key. This would be the only key embedded in cpackget? c) how about expiring keys or revoked keys. How do we make sure we don't need to update the signature for all packs that have been published already? ...
While testing cpackget on all packs from the public index, I've found packs under HTTP domains and packs with expired HTTPS certs. Should these be notified when installing packs? I'd say yes, but don't know if installation should be aborted.
Good points. I suggest that: a) add a command line option to allow download from http
b) if an https url has an expired certificate
Hi guys,
as usual I am going to be a bit pedantic and picky on the wording...so please feel free to kick my ass when needed :-)
To me, GPG is the GNU implementation of the OpenPGP standard: https://www.ietf.org/rfc/rfc4880.txt
So, my first point is: do you really want to rely on GPG which has a GPL-3.0 license ? I am not comfortable with this license.
Now, coming to OpenPGP. It describes many things, not only signatures. Typically it covers both encryption and signatures (even if section 2.5 states that we can need signatures only). This is more than we need.
To me, what we want is proving the authenticity and integrity of our packs. So, yes, we need to sign a pack.
But, to do so, we do not need OpenPGP in its wholeness. We just need asymmetric cryptography and a digest.
To be more precise, we need:
I would vote for ECDSA + SHA256 as we may work with "small" keys compared to RSA. And we may very well implement this with OpenSSL (Apache license) or ARM mbed TLS (Apache too). But, please, let's avoid GPL licenses...
I understand that you propose to have:
So, as a hacker I can:
This would be accepted by the tool if we have no "trusted third party" to certify the origin of the public key.
Countermeasure : we must prove the ownership of the public key.
So, to me, a smart and standard way to solve this issue is to use X.509 certificates to distribute the public keys (no need for a special server to register the authorized keys or hard-code the authorized keys in the cpackget binary).
Besides, with the X.509 certificates chain concept we can easily have a hierarchy of certificates and accept/revoke certificates at any level.
As a hacker, I may very well:
So, I can install any pack on my machine without cpackget checking it.
Countermeasure : the pack authenticity and integrity mustbe checked at usage step, not only at installation step.
So, each time the project manager uses a pack, it verifies its authenticity and integrity.
I recommend using X.509 certificates to distribute the public keys. This gives a great flexibility:
The tool would have a secure store of root certificates and it would be easy to maintain it (just like web browsers do). We just need to make sure a hacker cannot update the store with malicious certificates. But, tools vendors may maintain their own stores.
Or we may have specific CAs and if you want to publish a pack accepted by the tool then you must first obtain a public certificate signed by this CA. ST Micro may provide certificates to trusted partners so our implementation of cpackget would accept only these packs. ARM may do the same...etc...
Or, we may be permissive for some packs (libraries: accept any certificate) and restrictive for some others (device packs: accept only the certificates signed by silicon vendors CA).
Many strategies can be imagined... but X.509 is the building block for this IMO.
Maybe I should have started by this...but probably we need to clarify what we want to achieve here ?
To me what is important is:
That's why digital signature + PKI sounds good to me.
A 3rd goal may be:
For instance, if a pack is a CMSIS pack, then my tool may refuse to use this pack if it is not signed by ARM or a 3rd party whose certificate has been signed by ARM.
What do you think ?
We may have servers hosting some certificates but I guess it is not mandatory. The cpackget binary can have a "trusted certificates" store where we have at least the root CAs.
Then, the intermediate certs and leaf certificate signing the pack can be delivered together with the pack. That means that we would only need to distribute top level certificates to validate the lower level ones.
Of course, certs expiry must be considered. For the renewal it means we would have to issue a new pack revision with the updated certificates. But we may have "transition periods" where the tool is permissive. And also, packs issuer may use very long validity periods I guess.
Then it depends on the tool implementation:
So, I am more in favor of distributing the public keys together with the packs. It has the drawback that the pack may have to be republished when the validity period expires but it has the benefit of not requiring servers to distribute the keys (only the top level certs must be known by the tool to validate the certs chain).
The latest recommendations (for the web) seem to be to issue certificates with a one year validity period: https://www.globalsign.com/en/blog/maximum-ssltls-certificate-validity-now-one-year
But the Root CAs themselves have much longer validity period:
So, probably we can go for longer validity periods in our case.
Anyway, we can have a configurable "cpackget" with a permissive mode.
The question is also: should the signature be checked only by cpackget when installing the pack? (so we assume that once the pack is installed on the local machine the security is fine).
Or shall the tool using the pack check the signature too ? I guess this is not in the direct scope of this repo.
Nevertheless, this may have an impact on the architecture : maybe the service to check the packs should be "externalized" from cpackget (or at least built with an external API?) so that any tool can use it ?
Regarding this point:
Q2: How to ensure that the pack was created by the vendor? Because of the nature of X.509 certs, it's possible to track a signing key up to its original ROOT CA. All Root CAs should be in a secure store trusted by cpackget.
This is the idea. Just to be sure we are on the same page if we take the example of ARM CMSIS.
We need in the certs chain an intermediate certificate from ARM. And, to trust this ARM certificate, we need it to be signed by a root certificate from a Certification Authority.
So one may imagine a certificate chain like this: Joachim's cert <-- signed by-- ARM certificate <--signed by-- Globalsign Root CA
Then having the "Globalsign Root CA" in your trusted store of certificates (maybe the one from your OS) is sufficient to trust the entire certs chain.
You just need to say:
CN = ARM packs issuing entity
OU = ARM Germany GmbH
O = ARM Ltd
L = Munich
S = Bavaria
C = DE
Another aspect also : to avoid making packs distribution too painful (people may want to distribute packs easily), all these checks must be configurable.
An end-user may say : I do not want any check, I accept any pack from anywhere, even if the pack is not signed at all.
Hi @fred-r, let me try to compile your comments' answers in this comment.
We may have servers hosting some certificates but I guess it is not mandatory.
Are there any public certs store out there as MIT or Ubuntu do for GPG public keys? Perhaps these servers will become handy when distributing or keeping the list of CRL.
The cpackget binary can have a "trusted certificates" store where we have at least the root CAs. Then, the intermediate certs and leaf certificate signing the pack can be delivered together with the pack. That means that we would only need to distribute top level certificates to validate the lower level ones.
Ack.
For the renewal it means we would have to issue a new pack revision with the updated certificates.
Do you know if cert renewal also requires new keys? If so, I'm afraid pack re-signing would be a recurring task for vendors.
But we may have "transition periods" where the tool is permissive. And also, packs issuer may use very long validity periods I guess.
My initial idea was exactly that. But now that I re-read this statement, I think perhaps cpackget could by default check for pack signatures and avoid it via special flags, e.g. --bypass-security
or some other wording. This would scream out at anyone who sees that, thus suggesting pack issuers to adopt new security measures sooner.
The question is also: should the signature be checked only by cpackget when installing the pack? ... Nevertheless, this may have an impact on the architecture : maybe the service to check the packs should be "externalized" from cpackget (or at least built with an external API?) so that any tool can use it ?
Agreed! In my initial proposal, I suggested to build a tool ("cpacksec") that could be used to generate keys, sign packs and verify signature. The idea was to have it both as a standalone tool and as a Golang API that cpackget could make use of. I think the principle remains the same for PKI/x509 certs. The upside is that we could customize it as we wish.
We need in the certs chain an intermediate certificate from ARM. And, to trust this ARM certificate, we need it to be signed by a root certificate from a Certification Authority. So one may imagine a certificate chain like this: Joachim's cert <-- signed by-- ARM certificate <--signed by-- Globalsign Root CA
I remember from one of our email threads that you didn't like the idea of having a single RootCA signing all vendors certs. Or am I missing something? I had in mind that ARM certificate would be the Root cert in this chain, that it would be the one with long expiration dates and that this would be shipped in cpackget's secure certs store.
For the Root CA cert : agree, any vendor must have the freedom to choose the CA signing his certificate. This way, the tool does not need to maintain its own store of root certs and can reuse the OS store.
I do.not think it is mandatory for ARM to play the role of the CA, this would be complex. What I suggest is that the ARM intermediate cert (and it can be any intermediate cert assignef to the subjectcARM Ltd by a CA) is required for packs whose vendor is ARM.
But, we also need to be careful : more security is great but it comes with constraints. Bypassing the security checks must be allowed (one may think that all this signing is overkill and that they want to trust anybody).
Let me write a scratch tool to start off on this thread, it'll be useful moving our discussion forward.
@fred-r Let me ask you something that crossed my mind: Do you think Vendors would want to re-use x509 certs? For instance, let's say ARM already has another x509 cert that ARM uses somewhere else in the company, do you think it makes sense for ARM to reuse that to sign packs? Or should we always ensure that the cert to sign packs are created specifically for this use.
Let me write a scratch tool to start off on this thread, it'll be useful moving our discussion forward.
@fred-r Let me ask you something that crossed my mind: Do you think Vendors would want to re-use x509 certs? For instance, let's say ARM already has another x509 cert that ARM uses somewhere else in the company, do you think it makes sense for ARM to reuse that to sign packs? Or should we always ensure that the cert to sign packs are created specifically for this use.
Mmmh....not sure here. Usually when you send a CSR to a CA you indicate the purpose of your key. So here we would not ask for an SSL certificate but probably more a code signing certificate...even if we are not publishing an executable but a pack. So, we would use a code signing certificate but not a standard code signing application, instead I assume we would use your cpacksec application (because we do not need our software to be recognized by the OS).
The difficulty comes when we introduce the intermediate company CA. Usually, a Root CA restricts what you can do with the certificate it issues for you. If you were allowed to sign any other certificate then you could misuse it (sign a counterfeit certificate with your valid certificate). So, the CA is likely to issue a certificate with this field: X509v3 Basic Constraints: critical CA:FALSE
This being said, your tool may very well accept this scheme (even if CA is set to FALSE), knowing that we do not use it to validate web sites. Our protection against counterfeiting would be checking that the issuer is also the vendor of the pack to make sure we cannot publish a pack claiming it is from ARM and signing it with a non-ARM certificate.
As you can see, there is still a little bit of thinking to do to make sure we do not reinvent the wheel:-)
As you can see, there is still a little bit of thinking to do to make sure we do not reinvent the wheel:-)
It sure does!
It might also be the case that vendors re-use some certs to sign a "Pack-Signer RootCA" and have that one saved in cpackget's secure store. This is getting interesting. The tool will have to be very flexible to accommodate everyone's needs
As you can see, there is still a little bit of thinking to do to make sure we do not reinvent the wheel:-)
It sure does!
It might also be the case that vendors re-use some certs to sign a "Pack-Signer RootCA" and have that one saved in cpackget's secure store. This is getting interesting. The tool will have to be very flexible to accommodate everyone's needs
Yes, and we should also think about people who want to publish a pack without all this signing infrastructure. Then, users may accept such packs or not.
I just saw this tool that might be useful if we ever opt for setting a cert issuer server: https://smallstep.com/
I'm working on a scratch tool that implements things openssl did in @fred-r 's example. I'm not trying to reinvent the wheel here, but instead, by doing so I can really learn about it and properly do the job. For instance, I didn't know you could generate a cert for very specific needs, like signing other certs or simply to encrypt user data.
Just for future reference, I've found this article about x509 & PKI: https://smallstep.com/blog/everything-pki/. It looks very thorough, I haven't finished reading it yet, it's a bit long too.
How would this affect local packs? We use software packs for internal libraries and probably don't want to have to start messing around with signing them. Just wanting to make sure this is a use case that isn't forgotten about!
In my opinion anyway, you should always have the possibility to disable the signature check by default. This signature check should be optional with the reference tools otherwise many people will be blocked.
But, for people who want more security, then the check could be enabled.
There's now a wiki page for proposals like this, which I added this feature to. Added the proposal Google Doc there for more technical discussion.
Updated the wiki page regarding the latest implementation and the needed discussion/two possible mechanisms to fully deploy this feature.
I'm glad to hear that signing is being added to CMSIS packs, I think this will give CMSIS Pack users real benefits.
I have a suggestion that I think will give a more thorough solution than is currently proposed and potentially save time. Many of the concepts of secure package delivery have been implemented by existing systems and the lessons that have been learned from those systems have been written into a project called The Update Framework (TUF).
TUF provides a flexible framework and specification that is designed to allow it to be adopted into any software update system including when retrofitting it as is the case for CMSIS packs. There is a lot of available reading material and videos explaining the benefits of TUF but to understand the potential benefits of implementing TUF over the benefits of implementing the currently proposal TUF's security page gives a list of the attacks and weaknesses it addresses.
DRAFT
Pack Signing Motivation
This is a proposal to make cpackget installation more secure through pack signing by tackling the following top use cases:
Design
The fundamental idea is to use keys signed by PKI/x509 certificates to sign packs and be later on validated by
cpackget
.Each vendor would be responsible for generating their Root CA, then generate sub-certificates depending on their needs. Example:
Aspects of the approach:
--ignore-validity-date
or--ignor-ownership
Q&A
The following questions have been asked during discussion of this proposal:
Q1: How to ensure that the pack file has not been modified? The signature file is just an encrypted hash sum of the pack file, so during signature checking, the hash of the pack will be re-generated and compared against the one embedded in the signature file.
Q2: How to ensure that the pack was created by the vendor? Because of the nature of X.509 certs, it's possible to track a signing key up to its original ROOT CA. All Root CAs should be in a secure store trusted by cpackget.
Q3: If a pack was signed by a key that is no longer valid, is there a solution without re-signing all packs signed with that key? No, re-signing is required because the key is no longer trusted by cpackget.