Re: [openssl-dev] [openssl-users] OpenSSL engine and TPM usage.
On Thu, 2017-10-26 at 13:57 +0200, Richard Levitte wrote: > In message gmail.com> on Wed, 25 Oct 2017 22:36:45 +0530, Jayalakshmi bhat .jayalaks...@gmail.com> said: > > bhat.jayalakshmi> Our device uses TPM to protect certificate private > bhat.jayalakshmi> keys. We have written engine interface to integrate > bhat.jayalakshmi> TPM functionality into OpenSSL. Thus TPM gets > loaded > bhat.jayalakshmi> as an engine instance. Also we have mapped RSA > bhat.jayalakshmi> operations to TPM APIS as like > encryption/decryption > bhat.jayalakshmi> etc. > bhat.jayalakshmi> > bhat.jayalakshmi> Now we are into few issues. there are few > bhat.jayalakshmi> applications that wants to use application specific > bhat.jayalakshmi> identity certificate. In such cases RSA APIs should > bhat.jayalakshmi> not get mapped to TPM APIs. > bhat.jayalakshmi> > bhat.jayalakshmi> I wanted to know when we use engine instance for > bhat.jayalakshmi> encyrption/decryption operation, can it be done > bhat.jayalakshmi> selectively? > > Yes, it should be possible. However, this is up to the application, > not to your engine. The engine simply offers methods, the > application > chooses to use some or all of them as default algo implementations > through the diverse ENGINE_set_default* functions. > > For keys such as RSA ones, you can simply create the resulting > fetched > key with RSA_new_method(e), where |e| is your TPM engine, and your > engine's RSA method will be attached to that key rather than the > default. Unless you have a Firmware TPM, you really don't want to override the default methods, all you want to do is load and engine based key and override only specific key methods which are useful. The reason is the TPM is really slow, so you want the native system to do all the crypto operations it can rather than routing them through the TPM. So, for instance, if you look at the elliptic curve overrides for the tpm2 engine, https://git.kernel.org/pub/scm/linux/kernel/git/jejb/openssl_tpm2_engine.git/ all it does is change the EC_KEY methods for sign and nothing else (so verify still uses non-TPM methods). James -- openssl-dev mailing list To unsubscribe: https://mta.openssl.org/mailman/listinfo/openssl-dev
Re: [openssl-dev] The new OpenSSL license should be made GPLv2 compatible
On Sat, 2017-03-25 at 21:48 +0100, Florian Weimer wrote: > * James Bottomley: > > > On Sat, 2017-03-25 at 16:10 +, Salz, Rich via openssl-dev > > wrote: > > > > > > > Please, in the final OpenSSL license text add the paragraph > > > > linked in the above LLVM mailing list as an exception to the > > > > Apache license. > > > > > > > > We should make sure using OpenSSL in GPLv2-only projects its > > > > possible without any trouble or concern for developers. > > > > > > The problem is that if it is distributed under the GPLv2 there is > > > no patent protection, and that is important to us. > > > > I've already told you once that this is a factually incorrect > > statement because (L)GPLv2 contains an implicit patent licence: > > I think the fact that Richard rejects dual licensing indicates that > it's not the lack of a licence that concerns him, but something else. > He calls it “patent protection”; I assume he refers to the weak > mutually assured destruction clause in the Apache license (the “If > You institute patent litigation against any entity” part). Oh, OK ... and Rich confirms that below. So I agree, GPLv2 doesn't have a patent retaliation clause. > I don't think the GPL, version 2, contains anything remote close to > *that*, implied or otherwise. No; the closest is clause 7 which basically shuts down distribution for everyone in the event of a successful patent assertion. You could also characterise that as a mutually assured destruction clause. However both of these only work if the asserting entity needs the rights that are blocked. Unfortunately the most problematic assertions nowadays are done by troll entities who don't need any rights from us. James -- openssl-dev mailing list To unsubscribe: https://mta.openssl.org/mailman/listinfo/openssl-dev
Re: [openssl-dev] The new OpenSSL license should be made GPLv2 compatible
On Sat, 2017-03-25 at 16:10 +, Salz, Rich via openssl-dev wrote: > > > Please, in the final OpenSSL license text add the paragraph linked > > in the above LLVM mailing list as an exception to the Apache > > license. > > > > We should make sure using OpenSSL in GPLv2-only projects its > > possible without any trouble or concern for developers. > > The problem is that if it is distributed under the GPLv2 there is no > patent protection, and that is important to us. I've already told you once that this is a factually incorrect statement because (L)GPLv2 contains an implicit patent licence: https://mta.openssl.org/pipermail/openssl-dev/2017-March/009208.html but you can have it from a more authoritative source if you like: https://copyleft.org/guide/comprehensive-gpl-guidech7.html Additionally, since under Apache-2.0 the explicit patent grants are captured on contribution, they can't be lost again by the act of using the LLVM exception to distribute a portion of the code under another licence. James -- openssl-dev mailing list To unsubscribe: https://mta.openssl.org/mailman/listinfo/openssl-dev
Re: [openssl-dev] License change agreement
On Fri, 2017-03-24 at 20:24 +0100, Kurt Roeckx wrote: > On Fri, Mar 24, 2017 at 12:22:14PM -0700, James Bottomley wrote: > > > > This is my understanding as well. From the GPL side, for both > > dynamic > > and static linking of openssl to GPLv2 code, the section 3 system > > exception applies. > > Not everybody agrees that it applies. debian-legal is OK with shipping other libraries which require the system exception to link with GPLv2 code, so I don't find their position to be entirely self consistent. Regardless, if you move to Apache-2.0 you'll still use the system exception to link with GPLv2 code, but it will be much more acceptable. James -- openssl-dev mailing list To unsubscribe: https://mta.openssl.org/mailman/listinfo/openssl-dev
Re: [openssl-dev] License change agreement
On Fri, 2017-03-24 at 20:02 +0100, Florian Weimer wrote: > * Quanah Gibson-Mount: > > > Zero people that I know of are saying to switch to the GPL. What > > is being pointed out is that the incompatibility with the current > > OpenSSL license with the GPLv2 has been a major problem. > > The alleged incompatibility of OpenSSL with the GPLv2 has been used > to promote GNUTLS in the past (and to a much lesser extent, a certain > crypto consolidation effort intending to switch everything to NSS). > But GNUTLS has since left the GNU project, and I'm not aware of > anyone on the distribution side still saying that the old OpenSSL > license (particular when used as a dynamically-linked system library) > and the GPLv2 are incompatible. It's just not considered a problem > anymore. This is my understanding as well. From the GPL side, for both dynamic and static linking of openssl to GPLv2 code, the section 3 system exception applies. James -- openssl-dev mailing list To unsubscribe: https://mta.openssl.org/mailman/listinfo/openssl-dev
Re: [openssl-dev] License change agreement
On Fri, 2017-03-24 at 12:03 -0700, Quanah Gibson-Mount wrote: > --On Friday, March 24, 2017 12:30 PM -0700 James Bottomley > wrote: > > > > > Probably illegal and definitely immoral, in my opinion. Copyright > > > law > > > exists to protect authors from these kind of practises. > > > > I think you misunderstand the legal situation. Provided notice is > > sufficiently widely distributed and a reasonable period is allowed > > for > > objections it will become an estoppel issue after the licence is > > changed, which means anyone trying to object after the fact of the > > change will have to get a court order based on irreperable harm and > > show a good faith reason for not being able to object in the time > > period allowed. In the US, this sort of notice plus period for > > objection is standard for quite a few suits and the range of things > > which qualify as "good faith reason" are correspondingly very > > limited. > > It's not clear to me that that's correct. From > <http://blogs.fsfe.org/ciaran/?p=58> (See update), it appears you > need an explicit 95% permission rate to legally relicense and zero > objections. There's no legal basis for those figures (I think they're just examples: Mozilla was happy with 95% but that doesn't mean everyone else doing the same thing would have to gain 95%). The more explicit responses you get, the greater your case for having given proper notice, but there's no case law that I'm aware of on the exact percentages. > So far one objection has already surfaced. This is a more compelling problem: if a contributor actively objects within the notice period, the only real recourse is to rewrite their code (or reason them in to acquiescence). James -- openssl-dev mailing list To unsubscribe: https://mta.openssl.org/mailman/listinfo/openssl-dev
Re: [openssl-dev] License change agreement
On Fri, 2017-03-24 at 13:17 +, Salz, Rich via openssl-dev wrote: > > As was noted back when this was brought up in 2015, there are > > other, better, licenses than the APLv2 which are also GPLv2 > > compatible. The MPLv2 being an example of such a license. There > > is also BSD, MIT/X11, etc. The GPLv2 incompatibility of OpenSSL > > is a major problem. > > Better in one dimension, not in the multiple dimensions that we are > concerned about. For example, one of the major things that is an > issue for GPLv2 is the patent protection. Patent protection is > important to us. At least now we're compatible with GPL3, which is > hopefully seen as a major step forward. There seems to be a misunderstanding here: for starters licensing any library under GPLv2 is problematic because of the viral nature (it's mostly done as a ploy for open core business models), so I'm assuming you mean LGPLv2 (or 3) which would allow linking to non GPL code? Secondly the GPLv2 family of licences has strong implicit patent licences which GPLv3 made explicit. In terms of broad protection there's no real difference (as long as the patent owner ships the code, they can't sue). Explicit gives you a measure of protection on contributions if the owner leaves the community for some reason, but it's a much weaker protection than if they remain in the community (applies only to contributions as opposed to entire code base). James > Yes, it is too bad we can't please all communities right now. -- openssl-dev mailing list To unsubscribe: https://mta.openssl.org/mailman/listinfo/openssl-dev
Re: [openssl-dev] License change agreement
On Fri, 2017-03-24 at 10:06 +0100, Otto Moerbeek wrote: > On Fri, Mar 24, 2017 at 09:40:16AM +0100, Kurt Roeckx wrote: > > > On Fri, Mar 24, 2017 at 08:36:02AM +0100, Otto Moerbeek wrote: > > > On Fri, Mar 24, 2017 at 08:21:49AM +0100, Marcus Meissner wrote: > > > > > > > On Fri, Mar 24, 2017 at 07:48:58AM +0100, Otto Moerbeek wrote: > > > > > On Fri, Mar 24, 2017 at 04:11:48AM +, Blumenthal, Uri - > > > > > 0553 - MITLL wrote: > > > > > > > > > > > Apache license is fine for me, while GPL could be > > > > > > problematic. Incompatibility with GPLv2 is not a problem > > > > > > for us. > > > > > > > > > > > > If it is a problem for somebody - feel free to explain the > > > > > > details. Though I think the decision has been made, and the > > > > > > majority is OK with it. > > > > > > > > > > I like to mention that any license change cannot be made > > > > > based on a majority vote or any other method other than > > > > > getting each author (or its legal representative) to > > > > > *explicitly* allow the change. The method of "nothing heard > > > > > equals consent" is not valid in any jurisdiction I know of. > > > > > > > > > > While I'm not a contributor (I think I only sent in a small > > > > > diff years ago), I would like to stress that the planned > > > > > relicensing procedure is not legal and can be challenged in > > > > > court. > > > > > > > > Well, emails were sent yesterday out to _all_ contributors for > > > > ack/deny the change. > > > > > > Read the last line of the mail, it says the no reactions equals > > > consent. That is the illegal part. > > > > The legal advice we got said that we should do our best to contact > > people. If we contacted them, they had the possibility to say no. > > We will give them time and go over all people that didn't reply to > > try to reach them. > > > > But if they don't reply, as said, we will assume they have no > > problem with the license change. If at some later point in time > > they do come forward and say no, we will deal with that at that > > time. > > > > > > Kurt > > Probably illegal and definitely immoral, in my opinion. Copyright law > exists to protect authors from these kind of practises. I think you misunderstand the legal situation. Provided notice is sufficiently widely distributed and a reasonable period is allowed for objections it will become an estoppel issue after the licence is changed, which means anyone trying to object after the fact of the change will have to get a court order based on irreperable harm and show a good faith reason for not being able to object in the time period allowed. In the US, this sort of notice plus period for objection is standard for quite a few suits and the range of things which qualify as "good faith reason" are correspondingly very limited. James -- openssl-dev mailing list To unsubscribe: https://mta.openssl.org/mailman/listinfo/openssl-dev
Re: [openssl-dev] [TrouSerS-tech] [tpmdd-devel] [PATCH 1/1] add TPM2 version of create_tpm2_key and libtpm2.so engine
On Tue, 2017-01-03 at 16:40 -0700, Jason Gunthorpe wrote: > On Tue, Jan 03, 2017 at 03:22:56PM -0800, James Bottomley wrote: > > > I think it is very important to natively support the sign-only > > > key usage restriction. TPM1.2 goes so far as to declare keys that > > > can be used for arbitary decrypt as 'legacy do not use'. > > > > > > IMHO the best way to do this is to look at the sign operation > > > openssl is trying to do and see if it can be sent down the sign > > > path to the TPM. Only if that fails should the decrypt path be > > > used. > > > > The problem is the MD5-SHA1 signature of SSL and TLS < v1.2. This > > cannot be performed by the TPM because it's not listed as a > > supported signature, so the choice is either to deprecate these > > protocols (not really viable since they're in wide use in old > > websites) or use decrypt to do the signatures. Once we get to the > > point of having to use decrypt, there's no reason to preserve the > > signing distinction since we never know when a key will be used to > > decrypt or sign. > > I'm not disputing your analysis, just remarking that it seem very > undesirable to ban *all* sign-only keys just to support a single > legacy SSL configuration. It's not just a single situation. MD5-SHA1 is where it will fall apart on backwards compatibility but my current TPM doesn't understand anything other than sha1 or sha256, so it wouldn't allow more state of the art algorithms like sha224, sha384 or sha512 either. > This is why I suggest looking at the sign being requested and using > the sign path if it is *possible*, otherwise requiring a key with the > broader key usage. It's a trade off: the user configuration nightmare: how does an ordinary user know what type of TPM key they need ... they'll need to know what their TPM is capable of and what signatures they're likely to need. VS the benefits of having single use keys. I'm just not sure I see enough benefits to trying to preserve the decrypt vs sign distinction, whereas I do see the floods of complaints from users who got it wrong or think it should work as advertised. > Not everything is SSL - openssh uses these routines too and it should > be able to use the sign only key type without a limitation? Agreed that openssh only has forward compatibility problems, but it still has them thanks to the newer algorithm problem. Actually, the next problem would be gnome-keyring. It does openssl signatures and fishing the algorithm type out by the time James -- openssl-dev mailing list To unsubscribe: https://mta.openssl.org/mailman/listinfo/openssl-dev
Re: [openssl-dev] [PATCH 1/1] add TPM2 version of create_tpm2_key and libtpm2.so engine
On Wed, 2017-01-04 at 00:04 +, Matt Caswell wrote: > > On 03/01/17 12:44, Salz, Rich wrote: > > > > I'm still waiting on a reply ... I assume holidays are > > > > contributing to the delay. > > > > However, openssl_tpm_engine is a DCO project, so that concern > > > > is > > > > irrelevant here. > > > > > > Sorry, I'll push to get the bylaws made public, is that what you > > > need? > > > > The OSF bylaws are now linked to from > > https://www.openssl.org/policies/ > > I can't actually see this link...am I just missing it, or did you not > push? https://www.openssl.org/policies/osf-bylaws.pdf Thanks for doing this! James -- openssl-dev mailing list To unsubscribe: https://mta.openssl.org/mailman/listinfo/openssl-dev
Re: [openssl-dev] [PATCH 1/1] add TPM2 version of create_tpm2_key and libtpm2.so engine
On Tue, 2017-01-03 at 12:19 +0100, Richard Levitte wrote: > There seems to be some confusion here. > > James, I understand the tpm engine as an external project, not part > of the OpenSSL source proper and not intended to be. > > However, openssl-dev@openssl.org is a list focused on the development > of OpenSSL proper. That makes it a bit odd to discuss the tpm engine > here. Largely off topic. Fair enough. You were cc'd since it's a modification of code used by openSSL, in case there was interest. James > Cheers > Richard > > Skickat från BlueMail > > Den 2 jan. 2017 19:22, kI 19:22, "Salz, Rich" > skrev: > > > Really, how? By pull request, you mean one against the openssl > > github > > > account so people subscribing to that account see it, I presume? > > > For > > that to > > > happen, the tree the patch is against must actually exist within > > > the > > account, > > > which this one doesn't. > > > > You clone the openssl git repo, create your own branch off master, > > apply the diffs you are mailing to the list, and commit/push and > > then > > make a PR. Yes it's a bit of work for you. But it then becomes > > near-zero work for anyone on openssl to look at it. > > > > > This patch is mostly FYI, so yes, I do given that multiple > > > mailing > > lists have > > > some interest. > > > > It's all about trade-offs. Multiple people have said multiple > > times > > that PR's are the best way to work with OpenSSL. If those other > > groups, individually or collectively, are higher on your priority > > list, > > that's fine. But do understand what's going on. > > > > > I'm still waiting on a reply ... I assume holidays are > > > contributing > > to the delay. > > > However, openssl_tpm_engine is a DCO project, so that concern is > > irrelevant > > > here. > > > > Sorry, I'll push to get the bylaws made public, is that what you > > need? > > > > And no, it's not irrelevant. If this is ever going to appear in > > OpenSSL, a CLA must be signed. > > > > -- > > openssl-dev mailing list > > To unsubscribe: > > https://mta.openssl.org/mailman/listinfo/openssl-dev -- openssl-dev mailing list To unsubscribe: https://mta.openssl.org/mailman/listinfo/openssl-dev
Re: [openssl-dev] [PATCH 1/1] add TPM2 version of create_tpm2_key and libtpm2.so engine
On Mon, 2017-01-02 at 18:22 +, Salz, Rich wrote: > > I'm still waiting on a reply ... I assume holidays are contributing > > to the delay. However, openssl_tpm_engine is a DCO project, so that > > concern is irrelevant here. > > Sorry, I'll push to get the bylaws made public, is that what you > need? There were two requests: the bylaws and whether modified grant would be acceptable. If, instead of an unrestricted grant in the CLA it were restricted to relicensing to an OSI approved licence, the need to do due diligence on the foundation goes away. > And no, it's not irrelevant. If this is ever going to appear in > OpenSSL, a CLA must be signed. It's not actually my code: I'm just updating it, so I'm unable to say what the long term plan actually is. I would think, though, that hardware engines, since they're highly OS support dependent, would be difficult to keep within openssl itself given that you want to compile on multiple platforms. James -- openssl-dev mailing list To unsubscribe: https://mta.openssl.org/mailman/listinfo/openssl-dev
Re: [openssl-dev] [TrouSerS-tech] [tpmdd-devel] [PATCH 1/1] add TPM2 version of create_tpm2_key and libtpm2.so engine
On Tue, 2017-01-03 at 16:11 -0700, Jason Gunthorpe wrote: > On Sat, Dec 31, 2016 at 02:52:43PM -0800, James Bottomley wrote: > > This patch adds RSA signing for TPM2 keys. There's a limitation to > > the way TPM2 does signing: it must recognise the OID for the > > signature. That fails for the MD5-SHA1 signatures of the TLS/SSL > > certificate verification protocol, so I'm using RSA_Decrypt for > > both signing (encryption) and decryption ... meaning that this only > > works with TPM decryption keys. It is possible to use the prior > > code, which preserved the distinction of signing and decryption > > keys, but only at the expense of not being able to support SSL or > > TLS lower than 1.2 > > [Note, I haven't looked closely at TPM2, but TPM1.2 has a concept of > key usage, and I assume that is carried over in the below comments] The TPM1.2 all uses the correct signing functions, the problem is only with 2.0. > I think it is very important to natively support the sign-only key > usage restriction. TPM1.2 goes so far as to declare keys that can be > used for arbitary decrypt as 'legacy do not use'. > > IMHO the best way to do this is to look at the sign operation openssl > is trying to do and see if it can be sent down the sign path to the > TPM. Only if that fails should the decrypt path be used. The problem is the MD5-SHA1 signature of SSL and TLS < v1.2. This cannot be performed by the TPM because it's not listed as a supported signature, so the choice is either to deprecate these protocols (not really viable since they're in wide use in old websites) or use decrypt to do the signatures. Once we get to the point of having to use decrypt, there's no reason to preserve the signing distinction since we never know when a key will be used to decrypt or sign. Note that google took an alternative approach and modified their TSS to work with a MD5-SHA1 signature: https://chromium-review.googlesource.com/#/c/420811/ But this requires a modification to the TPM as well, which we can't do. > For TPM1.2 you could create a sign-only key with the > TPM_SS_RSASSAPKCS1v15_DER mode and feed it arbitary NIDs - the TPM > did not check the data to sign, AFAIK. > > Ideally the user should be able to setup a sign-only key and the > correct SSL negotiation parameters and have a working system, eg a > sign-only key used with TLS 1.3 and ephemeral keyx should work. > > > + /* this is slightly paradoxical that we're doing a Decrypt > > +* operation: the only material difference between decrypt > > and > > +* encrypt is where the padding is applied or checked, so > > if > > +* you apply your own padding up to the RSA block size and > > use > > +* TPM_ALG_NULL, which means no padding check, a decrypt > > +* operation effectively becomes an encrypt */ > > IIRC this duality is exactly why key usage exists, and why good > crypto practice has been to forbid decrypt/encrypt on the same key. Given the signature restrictions, TPM 2.0 just can't be made to work with the older SSL/TLS protocols, so I'm opting to keep compatibility and not benefit from the distinction between signing and decryption keys. James > Jason > > - > - > Check out the vibrant tech community on one of the world's most > engaging tech sites, SlashDot.org! http://sdm.link/slashdot > ___ > TrouSerS-tech mailing list > trousers-t...@lists.sourceforge.net > https://lists.sourceforge.net/lists/listinfo/trousers-tech > -- openssl-dev mailing list To unsubscribe: https://mta.openssl.org/mailman/listinfo/openssl-dev
Re: [openssl-dev] [PATCH 1/1] add TPM2 version of create_tpm2_key and libtpm2.so engine
On Mon, 2017-01-02 at 17:53 +, Salz, Rich wrote: > > Um, that's not really possible given that openssl_tpm_engine is a > > sourceforge project. > > Sure it is. Really, how? By pull request, you mean one against the openssl github account so people subscribing to that account see it, I presume? For that to happen, the tree the patch is against must actually exist within the account, which this one doesn't. > You just find it easier to email patches. This patch is mostly FYI, so yes, I do given that multiple mailing lists have some interest. > This is now the second time you’ve been asked. > > And also, you had concerns about the CLA before. Have they been > resolved? If not you should probably stop. I'm still waiting on a reply ... I assume holidays are contributing to the delay. However, openssl_tpm_engine is a DCO project, so that concern is irrelevant here. James -- openssl-dev mailing list To unsubscribe: https://mta.openssl.org/mailman/listinfo/openssl-dev
Re: [openssl-dev] [PATCH 1/1] add TPM2 version of create_tpm2_key and libtpm2.so engine
On Mon, 2017-01-02 at 17:38 +0100, Kurt Roeckx wrote: > On Sat, Dec 31, 2016 at 02:52:43PM -0800, James Bottomley wrote: > > This patch adds RSA signing for TPM2 keys. There's a limitation to > > the way TPM2 does signing: it must recognise the OID for the > > signature. That fails for the MD5-SHA1 signatures of the TLS/SSL > > certificate verification protocol, so I'm using RSA_Decrypt for > > both signing (encryption) and decryption ... meaning that this only > > works with TPM decryption keys. It is possible to use the prior > > code, which preserved the distinction of signing and decryption > > keys, but only at the expense of not being able to support SSL or > > TLS lower than 1.2 > > Please submit patches via github. Um, that's not really possible given that openssl_tpm_engine is a sourceforge project. James -- openssl-dev mailing list To unsubscribe: https://mta.openssl.org/mailman/listinfo/openssl-dev
[openssl-dev] [PATCH 1/1] add TPM2 version of create_tpm2_key and libtpm2.so engine
This patch adds RSA signing for TPM2 keys. There's a limitation to the way TPM2 does signing: it must recognise the OID for the signature. That fails for the MD5-SHA1 signatures of the TLS/SSL certificate verification protocol, so I'm using RSA_Decrypt for both signing (encryption) and decryption ... meaning that this only works with TPM decryption keys. It is possible to use the prior code, which preserved the distinction of signing and decryption keys, but only at the expense of not being able to support SSL or TLS lower than 1.2 Signed-off-by: James Bottomley --- v2: - use TPM2_RSA_Decrypt for both decryption and signing operations - Add authority processing - Add TPM internal key creation - allow persistent parents - update to use transient connections to the TPM --- Makefile.am | 12 +- create_tpm2_key.c | 451 +++ e_tpm2.c | 559 ++ tpm2-asn.h| 59 ++ tpm2-common.c | 175 + tpm2-common.h | 10 + 6 files changed, 1264 insertions(+), 2 deletions(-) create mode 100644 create_tpm2_key.c create mode 100644 e_tpm2.c create mode 100644 tpm2-asn.h create mode 100644 tpm2-common.c create mode 100644 tpm2-common.h diff --git a/Makefile.am b/Makefile.am index 6695656..fb4f529 100644 --- a/Makefile.am +++ b/Makefile.am @@ -2,12 +2,20 @@ SUBDIRS=. test EXTRA_DIST = README openssl.cnf.sample -openssl_engine_LTLIBRARIES=libtpm.la -bin_PROGRAMS=create_tpm_key +openssl_engine_LTLIBRARIES=libtpm.la libtpm2.la +bin_PROGRAMS=create_tpm_key create_tpm2_key openssl_enginedir=@libdir@/openssl/engines libtpm_la_LIBADD=-lcrypto -lc -ltspi libtpm_la_SOURCES=e_tpm.c e_tpm.h e_tpm_err.c +libtpm2_la_LIBADD=-lcrypto -lc -ltss +libtpm2_la_SOURCES=e_tpm2.c tpm2-common.c +libtpm2_la_CFLAGS=-g -Werror + create_tpm_key_SOURCES=create_tpm_key.c create_tpm_key_LDADD=-ltspi + +create_tpm2_key_SOURCES=create_tpm2_key.c tpm2-common.c +create_tpm2_key_LDADD=-lcrypto -ltss +create_tpm2_key_CFLAGS=-Werror diff --git a/create_tpm2_key.c b/create_tpm2_key.c new file mode 100644 index 000..ca3b38f --- /dev/null +++ b/create_tpm2_key.c @@ -0,0 +1,451 @@ +/* + * + * Copyright (C) 2016 James Bottomley + * + * GPLv2 + */ + + +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include + +#include +#include +#include + +#include "tpm2-asn.h" +#include "tpm2-common.h" + +static struct option long_options[] = { + {"auth", 0, 0, 'a'}, + {"help", 0, 0, 'h'}, + {"key-size", 1, 0, 's'}, + {"name-scheme", 1, 0, 'n'}, + {"parent-handle", 1, 0, 'p'}, + {"wrap", 1, 0, 'w'}, + {0, 0, 0, 0} +}; + +static TPM_ALG_ID name_alg = TPM_ALG_SHA256; +static int name_alg_size = SHA256_DIGEST_SIZE; + +void +usage(char *argv0) +{ + fprintf(stderr, "\t%s: create a TPM key and write it to disk\n" + "\tusage: %s [options] \n\n" + "\tOptions:\n" + "\t\t-a|--auth require a password for the key [NO]\n" + "\t\t-h|--help print this help message\n" + "\t\t-s|--key-size key size in bits [2048]\n" + "\t\t-n|--name-scheme name algorithm to use sha1 [sha256] sha384 sha512\n" + "\t\t-p|--parent-handle persistent handle of parent key\n" + "\t\t-w|--wrap [file] wrap an existing openssl PEM key\n" + "\nReport bugs to %s\n", + argv0, argv0, PACKAGE_BUGREPORT); + exit(-1); +} + +void +openssl_print_errors() +{ + ERR_load_ERR_strings(); + ERR_load_crypto_strings(); + ERR_print_errors_fp(stderr); +} + +int +openssl_write_tpmfile(const char *file, BYTE *pubkey, int pubkey_len, + BYTE *privkey, int privkey_len, int empty_auth, + TPM_HANDLE parent) +{ + TSSLOADABLE tssl; + BIO *outb; + + /* clear structure so as not to have to set optional parameters */ + memset(&tssl, 0, sizeof(tssl)); + if ((outb = BIO_new_file(file, "w")) == NULL) { +fprintf(stderr, "Error opening file for write: %s\n", file); + return 1; + } + tssl.type = OBJ_txt2obj(OID_loadableKey, 1); + tssl.emptyAuth = empty_auth; + if ((parent & 0xff00) == 0x8100) { + tssl.parent = ASN1_INTEGER_new(); + ASN1_INTEGER_set(tssl.parent, parent); + } + tssl.pubkey = ASN1_OCTET_STRING_new(); + ASN1_STRING_set(tssl.pubkey, pubkey, pubkey_len); + tssl.privkey = ASN1_OCTET_STRING_new(); + ASN1_STRI
[openssl-dev] [PATCH 0/1] TPM2 engine support for openssl
This is a completed version of the original RFC. It's working now both on the TPM2 simulator and on real hardware (I've converted my laptop to TPM2). I've updated it to use the latest version of the ASN.1 for the key format (still using a TCG OID). I have it building here (it's what I'm currently using for my laptop VPNs): https://build.opensuse.org/package/show/home:jejb1:Tumbleweed/openssl_tpm_engine But note that this version also has experimental patches to activate the in-kernel TPM Resource Manager because for multiple applications TPM2 really doesn't work well without one. Since the patch for the RM is currently not upstream (yet), it's not going to work unless you have a patched kernel. James --- James Bottomley (1): add TPM2 version of create_tpm2_key and libtpm2.so engine Makefile.am | 12 +- create_tpm2_key.c | 451 +++ e_tpm2.c | 559 ++ tpm2-asn.h| 59 ++ tpm2-common.c | 175 + tpm2-common.h | 10 + 6 files changed, 1264 insertions(+), 2 deletions(-) create mode 100644 create_tpm2_key.c create mode 100644 e_tpm2.c create mode 100644 tpm2-asn.h create mode 100644 tpm2-common.c create mode 100644 tpm2-common.h -- 2.6.6 -- openssl-dev mailing list To unsubscribe: https://mta.openssl.org/mailman/listinfo/openssl-dev
Re: [openssl-dev] [gnutls-devel] Proposal for the ASN.1 form of TPM1.2 and TPM2 keys
On Mon, 2016-12-26 at 21:13 +0100, Nikos Mavrogianopoulos wrote: > My comment was on the claim of extendability of the format which as I > explained it is simply not true. As for example I already gave the > key usage extension. I am fine however with a non extendable format > as you proposed. OK, so I think the version is now superfluous, since if anything gets added it can be recognised by the tag and things not ready to parse that tag can reject it. That makes the final form TPMKey ::= SEQUENCE { typeOBJECT IDENTIFIER emptyAuth [0] EXPLICIT BOOLEAN OPTIONAL parent [1] EXPLICIT INTEGER OPTIONAL pubkey [2] EXPLICIT OCTET STRING OPTIONAL privkey OCTET STRING } I'll code the v2 patch using this form. James > On December 26, 2016 7:13:40 PM GMT+01:00, James Bottomley < > james.bottom...@hansenpartnership.com> wrote: > > On Mon, 2016-12-26 at 08:18 +0100, Nikos Mavrogianopoulos wrote: > > > I'd like both backwards and forward compatibility actually, > > > exactly > > > like x509. If an informational field is added like the key usage > > > that > > > I mentioned, I doubt you'd like all the previous consumers > > > incompatible. > > > > OK, so there's a fundamental difference between a v3 X509 > > certificate > > and a TPM key: An X509 certificate is a signature over a set of v1 > > TBS > > data, a public key and a bundle of attributes. To verify the > > certificate or extract the key, you don't need to know what the > > attributes are, so you can still "use" the certificate in that > > form. > > However, you can't get the v1 tool to obey the v3 constraints on > > the > > certificate because it doesn't understand them. > > > > The ASN.1 description of a TPM key contains the actual binary > > representation of the key plus a set of information which explains > > to > > the consuming code how to use the key. Since I can't think of a > > way of > > making use of the key without understanding all of the information > > about how to use it, I think it is beneficial that v1 consumers > > don't > > try to use v2 key information because the resulting failure will > > excite > > the TPM's dictionary attack protection. > > > > I gave an example of one such extension: policy authorisations, but > > they're definitely of the "if you don't understand these, you can't > > use > > the key" variety. Perhaps if you can give an example of a > > potentially > > compatible extensions it would help me to see your point and give > > us a > > means of moving forwards. > > > > Thanks, > > > > James > > > > > For other extensions which make the structure totally > > > incompatible > > > you can use the critical flag. Anyway even the original struct is > > > OK, > > > it is exactly like any other key structs we have. > -- openssl-dev mailing list To unsubscribe: https://mta.openssl.org/mailman/listinfo/openssl-dev
Re: [openssl-dev] [gnutls-devel] Proposal for the ASN.1 form of TPM1.2 and TPM2 keys
On Mon, 2016-12-26 at 08:18 +0100, Nikos Mavrogianopoulos wrote: > I'd like both backwards and forward compatibility actually, exactly > like x509. If an informational field is added like the key usage that > I mentioned, I doubt you'd like all the previous consumers > incompatible. OK, so there's a fundamental difference between a v3 X509 certificate and a TPM key: An X509 certificate is a signature over a set of v1 TBS data, a public key and a bundle of attributes. To verify the certificate or extract the key, you don't need to know what the attributes are, so you can still "use" the certificate in that form. However, you can't get the v1 tool to obey the v3 constraints on the certificate because it doesn't understand them. The ASN.1 description of a TPM key contains the actual binary representation of the key plus a set of information which explains to the consuming code how to use the key. Since I can't think of a way of making use of the key without understanding all of the information about how to use it, I think it is beneficial that v1 consumers don't try to use v2 key information because the resulting failure will excite the TPM's dictionary attack protection. I gave an example of one such extension: policy authorisations, but they're definitely of the "if you don't understand these, you can't use the key" variety. Perhaps if you can give an example of a potentially compatible extensions it would help me to see your point and give us a means of moving forwards. Thanks, James > For other extensions which make the structure totally incompatible > you can use the critical flag. Anyway even the original struct is OK, > it is exactly like any other key structs we have. -- openssl-dev mailing list To unsubscribe: https://mta.openssl.org/mailman/listinfo/openssl-dev
Re: [openssl-dev] [gnutls-devel] Proposal for the ASN.1 form of TPM1.2 and TPM2 keys
On Sun, 2016-12-25 at 22:08 +0100, Nikos Mavrogiannopoulos wrote: > On Sun, Dec 25, 2016 at 7:44 PM, James Bottomley > wrote: > > > TPMKey ::= SEQUENCE { > > > typeOBJECT IDENTIFIER > > > version [0] IMPLICIT INTEGER OPTIONAL > > > emptyAuth [1] IMPLICIT BOOLEAN OPTIONAL > > > parent [2] IMPLICIT INTEGER OPTIONAL > > > publicKey [3] IMPLICIT OCTET STRING OPTIONAL > > > privateKey OCTET STRING > > > extensions [4] EXPLICIT Extensions OPTIONAL > > > } > > > > Actually, that's the utility of ASN.1, once you use tagging, you > > don't have to do this. The structure above is identical to: > > > > TPMKey ::= SEQUENCE { > > typeOBJECT IDENTIFIER > > version [0] IMPLICIT INTEGER OPTIONAL > > emptyAuth [1] IMPLICIT BOOLEAN OPTIONAL > > parent [2] IMPLICIT INTEGER OPTIONAL > > publicKey [3] IMPLICIT OCTET STRING OPTIONAL > > privateKey OCTET STRING > > } > > > > If tag 4 isn't present because optional tags are not coded when not > > present, so you can expand any ASN.1 structure as long as you have > > a clue from the version number that you should be looking for the > > optional extras. The point being I don't have to specify the > > expansion now, I can wait until we need it. > > How would that work for example if you want to add an additional > field with information on the type of the key for example (key > usage)? You would add the tag 4 as you say, and then all the previous > parsers written with the initial description will fail parsing the > new structure. X.509 (==PKIX) is only expandable via the extensions > field which is already defined. If you add a field to it, no parser > would be able to read the certificate. Um, well, you only want backwards compatibility, you don't really want forward compatibility. Assuming something extends the structure and adds version v2, why would it matter that an old v1 application can't read a v2 structure because it doesn't understand the tag 4? Even if it could it can't make use of the extra fields and something nasty will happen. What you want is that the new v2 application can parse both the v2 structure and the old v1 one, but it's advantageous that a v1 application fails with a v2 structure because it prevents cockups. James -- openssl-dev mailing list To unsubscribe: https://mta.openssl.org/mailman/listinfo/openssl-dev
Re: [openssl-dev] [gnutls-devel] Proposal for the ASN.1 form of TPM1.2 and TPM2 keys
On Sun, 2016-12-25 at 10:18 +0100, Nikos Mavrogiannopoulos wrote: > On Sat, Dec 24, 2016 at 5:13 PM, James Bottomley > wrote: > > > I think, since it's a key format, the two above are the potential > > ones. It would be TCG if they want to take it into their standard, > > otherwise PKCS is RSA Inc. > > I wouldn't expect RSA inc to be involved into this as part of PKCS. > They are dead long time ago and have moved to IETF. I think I should give TCG first crack at wanting to own the OID. The IETF ones are easy: once you codify it in an RFC, the oid registry auto extracts it. > > > However, I'm not sure how expandable is ASN.1 using version > > > fields (I've seen no structure being able to be re-used using a > > > different version). An alternative approach would to allow for > > > future extensions, i.e., something like the PKIX Extension field, > > > which is an OID+data. > > > > As long as the expansion fields are optional, it works nicely. > > X509 and X509v3 are examples of version expanded ASN.1 > > Only if they are defined in the structure early. Otherwise the early > versions of the implementations wouldn't cope with extensions. To > make it early extendable you'd have to use something lilke > > TPMKey ::= SEQUENCE { > typeOBJECT IDENTIFIER > version [0] IMPLICIT INTEGER OPTIONAL > emptyAuth [1] IMPLICIT BOOLEAN OPTIONAL > parent [2] IMPLICIT INTEGER OPTIONAL > publicKey [3] IMPLICIT OCTET STRING OPTIONAL > privateKey OCTET STRING > extensions [4] EXPLICIT Extensions OPTIONAL > } Actually, that's the utility of ASN.1, once you use tagging, you don't have to do this. The structure above is identical to: TPMKey ::= SEQUENCE { typeOBJECT IDENTIFIER version [0] IMPLICIT INTEGER OPTIONAL emptyAuth [1] IMPLICIT BOOLEAN OPTIONAL parent [2] IMPLICIT INTEGER OPTIONAL publicKey [3] IMPLICIT OCTET STRING OPTIONAL privateKey OCTET STRING } If tag 4 isn't present because optional tags are not coded when not present, so you can expand any ASN.1 structure as long as you have a clue from the version number that you should be looking for the optional extras. The point being I don't have to specify the expansion now, I can wait until we need it. I'm pretty certain the next expansion is actually SEQUENCE OF TPM2Policy but I'm still playing with the format. James -- openssl-dev mailing list To unsubscribe: https://mta.openssl.org/mailman/listinfo/openssl-dev
Re: [openssl-dev] [gnutls-devel] Proposal for the ASN.1 form of TPM1.2 and TPM2 keys
On Sat, 2016-12-24 at 14:25 +0100, Nikos Mavrogiannopoulos wrote: > On Fri, Dec 23, 2016 at 7:06 PM, James Bottomley > wrote: > > The reason this comes about is because we already have a standard > > form for TPM 1.2 keys here: > > http://david.woodhou.se/draft-woodhouse-cert-best-practice.html#ide > > nt-tpm > > However, since I'm working on TPM2 enabling for openssl and gnutls, > > I need to come up with a new key format because TPM2 requires some > > extra parameters and the original TSS KEY BLOB, being a single > > ASN1_OCTET_STRING isn't expandable. > [...] > > I'm torn on where to get the OIDs from. Since this is a TPM key, > > it might make sense to use the TCG OID (2.23.133) and just add > > something they haven't already used, like 10 for key formats, or we > > could go with a pkcs OID (1.2.840.113549.1) > > OIDs under some umbrella normally need to be registered within the > organization they belong to. If you cannot find a suitable > organization to get these OIDs from I'll check whether we can get > something under redhat's OIDs. I think, since it's a key format, the two above are the potential ones. It would be TCG if they want to take it into their standard, otherwise PKCS is RSA Inc. > > If we can agree on this, we can update David's document and make it > > a formal RFC. > > Shouldn't version be first? I put OID first because that's what makes the structure self describing. You simply need to look for the SEQUENCE OBJECT OID prefix. We can easily register our own, of course as well. If version goes first, you have a variable prefix. > However, I'm not sure how expandable is ASN.1 using version fields > (I've seen no structure being able to be re-used using a different > version). An alternative approach would to allow for future > extensions, i.e., something like the PKIX Extension field, which is > an OID+data. As long as the expansion fields are optional, it works nicely. X509 and X509v3 are examples of version expanded ASN.1 James -- openssl-dev mailing list To unsubscribe: https://mta.openssl.org/mailman/listinfo/openssl-dev
Re: [openssl-dev] Proposal for the ASN.1 form of TPM1.2 and TPM2 keys
On Fri, 2016-12-23 at 21:12 +0100, Richard Levitte wrote: > In message <1482516363.2501.34.ca...@hansenpartnership.com> on Fri, > 23 Dec 2016 10:06:03 -0800, James Bottomley < > james.bottom...@hansenpartnership.com> said: > > James.Bottomley> The reason this comes about is because we already > have a standard form > James.Bottomley> for TPM 1.2 keys here: > James.Bottomley> > James.Bottomley> http://david.woodhou.se/draft-woodhouse-cert-best-pr > actice.html#ident-tpm > James.Bottomley> > James.Bottomley> However, since I'm working on TPM2 enabling for > openssl and gnutls, I > James.Bottomley> need to come up with a new key format because TPM2 > requires some extra > James.Bottomley> parameters and the original TSS KEY BLOB, being a > single > James.Bottomley> ASN1_OCTET_STRING isn't expandable. > James.Bottomley> > James.Bottomley> As a digression, the extra parameters that TPM2 > needs are: > James.Bottomley> > James.Bottomley>1. A public key blob. In TPM12 the key complex > was a joint > James.Bottomley> public/private part. In TPM2, the public and > private key structures > James.Bottomley> have variable length and are supplied > separately. > James.Bottomley>2. a boolean for emptyAuth. In TPM12 there's a > way to tell if a > James.Bottomley> structure has no authorization. In TPM2 > there's no such thing as no > James.Bottomley> authorization, but there's a conventional > empty authorization to > James.Bottomley> replace it but no way of querying whether any > given key is using it, > James.Bottomley> so we need to know explicitly whether to > prompt for a password or > James.Bottomley> not. > James.Bottomley>3. There are different forms a TPM private key > could be in. One is > James.Bottomley> symmetrically encrypted with a TPM private > key, which makes it > James.Bottomley> loadable, meaning it must be produced on the > TPM itself and the > James.Bottomley> other is asymmetrically encrypted meaning it > can be produced away > James.Bottomley> from the TPM but must be imported before being > loaded. > James.Bottomley> > James.Bottomley> I think there's value in having a universal > structure for the key > James.Bottomley> representations, so I'm proposing an ASN1 > representation that will work > James.Bottomley> for both TPM1.2 and TPM2 keys. I'd also like it to > be self describing, > James.Bottomley> so I think we should use an OID as the initial > parameter of the > James.Bottomley> sequence. With that, I think the format that works > is > James.Bottomley> > James.Bottomley> TPMKey ::= SEQUENCE { > James.Bottomley>typeOBJECT IDENTIFIER > James.Bottomley>version [0] IMPLICIT INTEGER OPTIONAL > James.Bottomley>emptyAuth [1] IMPLICIT BOOLEAN OPTIONAL > James.Bottomley>parent [2] IMPLICIT INTEGER OPTIONAL > James.Bottomley>publicKey [3] IMPLICIT OCTET STRING > OPTIONAL > James.Bottomley>privateKey OCTET STRING > James.Bottomley> } > James.Bottomley> > James.Bottomley> Where TPM12 keys would have a TPM12Key type and use > no optional fields > James.Bottomley> (meaning only privateKey) and TPM2 keys would have > type TPM2LoadableKey > James.Bottomley> or TPM2ImportableKey type and then make use of all > the optional fields > James.Bottomley> (except version). > James.Bottomley> > James.Bottomley> Version is there for future expansion, but is unused > in the initial > James.Bottomley> incarnation. > James.Bottomley> > James.Bottomley> I'm torn on where to get the OIDs from. Since this > is a TPM key, it > James.Bottomley> might make sense to use the TCG OID (2.23.133) and > just add something > James.Bottomley> they haven't already used, like 10 for key formats, > or we could go with > James.Bottomley> a pkcs OID (1.2.840.113549.1) > James.Bottomley> > James.Bottomley> If we can agree on this, we can update David's > document and make it a > James.Bottomley> formal RFC. > James.Bottomley> > James.Bottomley> Thoughts? > > First reaction is +1, at least for actually making a universally > parsable description. Thanks. After playing more I think I'd like to make the tags explicit rather than implicit so I can see the contents easily with asn1parse (and we're not in any way pressed for space, which is the usual reason for implicit tags). > One detail that esc
[openssl-dev] Proposal for the ASN.1 form of TPM1.2 and TPM2 keys
The reason this comes about is because we already have a standard form for TPM 1.2 keys here: http://david.woodhou.se/draft-woodhouse-cert-best-practice.html#ident-tpm However, since I'm working on TPM2 enabling for openssl and gnutls, I need to come up with a new key format because TPM2 requires some extra parameters and the original TSS KEY BLOB, being a single ASN1_OCTET_STRING isn't expandable. As a digression, the extra parameters that TPM2 needs are: 1. A public key blob. In TPM12 the key complex was a joint public/private part. In TPM2, the public and private key structures have variable length and are supplied separately. 2. a boolean for emptyAuth. In TPM12 there's a way to tell if a structure has no authorization. In TPM2 there's no such thing as no authorization, but there's a conventional empty authorization to replace it but no way of querying whether any given key is using it, so we need to know explicitly whether to prompt for a password or not. 3. There are different forms a TPM private key could be in. One is symmetrically encrypted with a TPM private key, which makes it loadable, meaning it must be produced on the TPM itself and the other is asymmetrically encrypted meaning it can be produced away from the TPM but must be imported before being loaded. I think there's value in having a universal structure for the key representations, so I'm proposing an ASN1 representation that will work for both TPM1.2 and TPM2 keys. I'd also like it to be self describing, so I think we should use an OID as the initial parameter of the sequence. With that, I think the format that works is TPMKey ::= SEQUENCE { typeOBJECT IDENTIFIER version [0] IMPLICIT INTEGER OPTIONAL emptyAuth [1] IMPLICIT BOOLEAN OPTIONAL parent [2] IMPLICIT INTEGER OPTIONAL publicKey [3] IMPLICIT OCTET STRING OPTIONAL privateKey OCTET STRING } Where TPM12 keys would have a TPM12Key type and use no optional fields (meaning only privateKey) and TPM2 keys would have type TPM2LoadableKey or TPM2ImportableKey type and then make use of all the optional fields (except version). Version is there for future expansion, but is unused in the initial incarnation. I'm torn on where to get the OIDs from. Since this is a TPM key, it might make sense to use the TCG OID (2.23.133) and just add something they haven't already used, like 10 for key formats, or we could go with a pkcs OID (1.2.840.113549.1) If we can agree on this, we can update David's document and make it a formal RFC. Thoughts? James -- openssl-dev mailing list To unsubscribe: https://mta.openssl.org/mailman/listinfo/openssl-dev
[openssl-dev] [RFC 1/1] add TPM2 version of create_tpm2_key and libtpm2.so engine
Proof of concept patch to wrap RSA (and eventually other) keys in TPM2 format and use them to load into a TPM2 to perform signatures. This scheme has significant limitations over TPM1.2 in that TPM2 insists on knowing and validating the signature, so it will only sign stuff it knows the OID to. That's also why the signature has to be parsed into an X509_SIG before signing. Signed-off-by: James Bottomley --- Makefile.am | 12 +- create_tpm2_key.c | 381 ++ e_tpm2.c | 482 ++ tpm2-asn.h| 35 tpm2-common.c | 172 +++ tpm2-common.h | 10 ++ 6 files changed, 1090 insertions(+), 2 deletions(-) create mode 100644 create_tpm2_key.c create mode 100644 e_tpm2.c create mode 100644 tpm2-asn.h create mode 100644 tpm2-common.c create mode 100644 tpm2-common.h diff --git a/Makefile.am b/Makefile.am index 4932fae..a704d8c 100644 --- a/Makefile.am +++ b/Makefile.am @@ -2,12 +2,20 @@ SUBDIRS=. test EXTRA_DIST = README openssl.cnf.sample -openssl_engine_LTLIBRARIES=libtpm.la -bin_PROGRAMS=create_tpm_key +openssl_engine_LTLIBRARIES=libtpm.la libtpm2.la +bin_PROGRAMS=create_tpm_key create_tpm2_key openssl_enginedir=@libdir@/openssl/engines libtpm_la_LIBADD=-lcrypto -lc -ltspi libtpm_la_SOURCES=e_tpm.c e_tpm.h e_tpm_err.c +libtpm2_la_LIBADD=-lcrypto -lc -ltss +libtpm2_la_SOURCES=e_tpm2.c tpm2-common.c +libtpm2_la_CFLAGS=-g -Werror + create_tpm_key_SOURCES=create_tpm_key.c create_tpm_key_LDADD=-lcrypto -ltspi + +create_tpm2_key_SOURCES=create_tpm2_key.c tpm2-common.c +create_tpm2_key_LDADD=-lcrypto -ltss +create_tpm2_key_CFLAGS=-Werror diff --git a/create_tpm2_key.c b/create_tpm2_key.c new file mode 100644 index 000..001bf1d --- /dev/null +++ b/create_tpm2_key.c @@ -0,0 +1,381 @@ +/* + * + * Copyright (C) 2016 James Bottomley + * + * GPLv2 + */ + + +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include + +#include +#include +#include + +#include "tpm2-asn.h" +#include "tpm2-common.h" + +static struct option long_options[] = { + {"enc-scheme", 1, 0, 'e'}, + {"name-scheme", 1, 0, 'n'}, + {"key-size", 1, 0, 's'}, + {"auth", 0, 0, 'a'}, + {"popup", 0, 0, 'p'}, + {"wrap", 1, 0, 'w'}, + {"help", 0, 0, 'h'}, + {0, 0, 0, 0} +}; + +static TPM_ALG_ID name_alg = TPM_ALG_SHA256; +static int name_alg_size = SHA256_DIGEST_SIZE; + +void +usage(char *argv0) +{ + fprintf(stderr, "\t%s: create a TPM key and write it to disk\n" + "\tusage: %s [options] \n\n" + "\tOptions:\n" + "\t\t-e|--enc-scheme encryption scheme to use [PKCSV15] or OAEP\n" + "\t\t-n|--name-scheme name algorithm to use sha1 [sha256] sha384 sha512\n" + "\t\t-s|--key-sizekey size in bits [2048]\n" + "\t\t-a|--authrequire a password for the key [NO]\n" + "\t\t-p|--popup use TSS GUI popup dialogs to get the password " + "for the\n\t\t\t\t key [NO] (implies --auth)\n" + "\t\t-w|--wrap [file] wrap an existing openssl PEM key\n" + "\t\t-h|--helpprint this help message\n" + "\nReport bugs to %s\n", + argv0, argv0, PACKAGE_BUGREPORT); + exit(-1); +} + +void +openssl_print_errors() +{ + ERR_load_ERR_strings(); + ERR_load_crypto_strings(); + ERR_print_errors_fp(stderr); +} + +int +openssl_write_tpmfile(const char *file, BYTE *pubkey, int pubkey_len, + BYTE *privkey, int privkey_len) +{ + TSSLOADABLE tssl; + BIO *outb; + + if ((outb = BIO_new_file(file, "w")) == NULL) { +fprintf(stderr, "Error opening file for write: %s\n", file); + return 1; + } + tssl.pubkey = ASN1_OCTET_STRING_new(); + tssl.privkey = ASN1_OCTET_STRING_new(); + printf("setting pubkey len %d\n", pubkey_len); + ASN1_STRING_set(tssl.pubkey, pubkey, pubkey_len); + printf("setting privkey len %d\n", privkey_len); + ASN1_STRING_set(tssl.privkey, privkey, privkey_len); + + PEM_write_bio_TSSLOADABLE(outb, &tssl); + BIO_free(outb); + return 0; +} + +EVP_PKEY * +openssl_read_key(char *filename) +{ +BIO *b = NULL; + EVP_PKEY *pkey; + +b = BIO_new_file(filename, "r"); +if (b == NULL) { +fprintf(stderr, "Error opening file for read: %s\n", filename); +return NULL; +} + +if ((
[openssl-dev] [RFC 0/1] TPM2 engine support for openssl
This is a basic RFC to show that it's possible to get TPM2 to act as an engine for openssl as well as TPM1.2. The format follows as closely as possible what happens in TPM1.2. The file format is full blown ASN.1 because we have to include both a public and private key blob. I chose to use TSS2 KEY BLOB as the guards to distinguish it from the TPM1.2 file. TPM2 has significant limitations over TPM1.2 in what it will sign: basically it must recognise the signature algorithm (that's why all the signature parsing in the rsa_priv_enc() routine). There's also another problem in that a primary asymmetric key of the SPS must be provisioned every time we perform this operation (which is time consuming and annoying). I think we need to do something about this under Linux, but I'll take that off the openssl list because they likely won't be interested. The authority handling is missing at the moment, but I'll add that shortly. We should probably discuss how policy based authorisation should be handled: I think as extensions to the key ASN.1 file. Because of the signature recognition problem, you have to test this out with x509 certificates: openssl genrsa 2048 > tmp.key create_tpm2_key -w tmp.key tmp.bin openssl req -new -engine tpm2 -key tmp.bin -keyform e > tmp.csr openssl x509 -req -engine tpm2 -in tmp.csr -signkey tmp.bin -keyform e -out tmp.crt openssl x509 -text -in tmp.crt The last step will validate you've got a genuine x509 self signed certificate with the key from the TPM. This kit is constructed using the IBM TSS2: https://sourceforge.net/projects/ibmtpm20tss/ And, at the moment, it's only been validated on a software TPM2. James --- James Bottomley (1): add TPM2 version of create_tpm2_key and libtpm2.so engine Makefile.am | 12 +- create_tpm2_key.c | 381 ++ e_tpm2.c | 482 ++ tpm2-asn.h| 35 tpm2-common.c | 172 +++ tpm2-common.h | 10 ++ 6 files changed, 1090 insertions(+), 2 deletions(-) create mode 100644 create_tpm2_key.c create mode 100644 e_tpm2.c create mode 100644 tpm2-asn.h create mode 100644 tpm2-common.c create mode 100644 tpm2-common.h -- 2.6.6 -- openssl-dev mailing list To unsubscribe: https://mta.openssl.org/mailman/listinfo/openssl-dev
Re: [openssl-dev] [RFC v2 0/2] Proposal for seamless handling of TPM based RSA keys in openssl
On Wed, 2016-12-14 at 17:05 +, David Woodhouse wrote: > On Wed, 2016-12-14 at 06:58 -0800, James Bottomley wrote: > > > Hm, this seems odd. If something is stored in a file then > > > exposing it through PKCS#11 doesn't make sense at all. Do not > > > attempt to use PKCS#11 for any file access. > > > > OK, so the horse has already left the stable on that one with TPM > > enabling gnome-keyring for ssh keys because it exports *every* key > > over pkcs11. Since it does, I thought I'd play about with it a bit > > to see how it would work. The below is what I found out playing > > around. > > I think we're talking about two different things. What I mean is that > a given application shall never have to deal with files and PKCS#11 > for a given single object. Sure (as in I thought that went without saying). > Like the nss-pem horridness, where we create an object whose > CKA_LABEL is the filename, and we want the soft token to > go and load that file. > > You seem to be talking about software-based PKCS#11 tokens which > happen to use their *own* files behind the scenes, but all the > *application* ever knows about is sane PKCS#11 operations. That is > absolutely fine. There's plenty of examples of that — including > SoftHSM, GNOME keyring, and NSS's softokn. Yes ... I was mostly reacting against your statement that the keys needed to be inside the TPM for PKCS11 use. > And you'll note that none of those examples need extensions to the > PKCS#8 format to store arbitrary PKCS#11 attributes such as > CKA_LABEL, CKA_PRIVATE, CKA_APPLICATION or anything else. Because > it's their own database and they can do what they like; they don't > have to store it in a PKCS#8 or similar file. OK, so as long as you're happy with pkcs11 being used on TPM key files which are then loaded as needed via the pkcs11 interface, I think we're on the same page. I'm coming to the conclusion that we need the files in pairs and the public key can supply the attributes ... it's more or less how gnome keyring currently does it. > The example you give with GNOME keyring doing SSH keys is a > *different* special case. There it's automatically discovering the > files in a known location (~/.ssh/id_*) and has to infer what it can > from them, but still it's only exposing them over PKCS#11 in a > standard way. There's none of the horridness for 'here, load *this* > file into the token', is there? You can do that with ssh-add perhaps, > but that's mostly orthogonal to what we're talking about here. OK, so a token can be writeable as well, but I expect the object to be loaded into the token to be correctly serialised according to the protocol and also possibly wrapped. > > So this is the actual problem: the TPM only stores private keys. > > The public key thing (can be simple, cert or something more fancy) > > isn't known to it. All pkcs11 searchers find the public key in the > > public objects and then look for the private key by id and label > > (this is what the standard recommends). > > Which part of the standard are you referring to? It isn't really that > prescriptive about how you look things up, as far as I was aware. Section 4.8 in the current OASIS base spec: The CKA_ID field is intended to distinguish among multiple keys. In the case of public and private keys, this field assists in handling multiple keys held by the same subject; the key identifier for a public key and its corresponding private key should be the same. The key identifier should also be the same as for the corresponding certificate, if one exists. In practice it seems that most things use CKA_ID and CKA_LABEL if they both exist. > > The problem is that the label they use isn't going to be the > > UUID, so we need the private key to be labelled by what its public > > counterpart expects to use the TPM for arbitrary keys, like > > certificate private keys (or even gpg or ssh private keys). The > > UUID thing works for stuff that expects separate private and public > > key descriptions, like gnutls and openssl, but not for anything > > that uses the full pkcs11 protocol (like netscape). > > Right, you need a full software token for stuff like NSS. But didn't > you already do that in GNOME keyring? It stores the CKO_CERTIFICATE > objects just like it always did, and now it's capable of storing the > actual private key of a CKO_PRIVATE object in TSS-wrapped form, but > the other attributes are still stored in its database just as they > always were? Yes, I can do it, but the TPM private keys are going to have to inherit the certificate C
Re: [openssl-dev] [RFC v2 0/2] Proposal for seamless handling of TPM based RSA keys in openssl
On Wed, 2016-12-14 at 09:07 +, David Woodhouse wrote: > On Tue, 2016-12-13 at 16:49 -0800, James Bottomley wrote: > > > > So the proposal is to have a TPM specific value for > > PrivateKeyAlgorithm (which would have to be proposed as an OID) and > > use PrivateKeyInfo for the key? That could be made to work. > > Right. > > > The slight fly in the ointment that's worrying me is that I need a > > key format that works for pkcs#11 tokens as well. The problem here > > is that TPM keys don't have an id or a label and that's pretty much > > a requirement of using a pkcs#11 token, so the pkcs#11 code has to > > be able to set these attributes on the key files. I was originally > > thinking of putting them into the PEM header with a pkcs11- prefix. > > I suppose I can do the same with the attributes and some > > manufactured OID prefix with the CKA_ parameters we're interested > > in as a suffix but it's messy. > > Hm, this seems odd. If something is stored in a file then exposing it > through PKCS#11 doesn't make sense at all. Do not attempt to use > PKCS#11 for any file access. OK, so the horse has already left the stable on that one with TPM enabling gnome-keyring for ssh keys because it exports *every* key over pkcs11. Since it does, I thought I'd play about with it a bit to see how it would work. The below is what I found out playing around. > Seriously, if you have any doubts about that at all, go read nss-pem > and ponder its operation. Then drink until you've forgotten most of > it, but remember that PKCS#11 isn't to be used for accessing stuff > that you have in a file. > > PKCS#11 can sanely be used for keys which are persistently stored > *in* the TPM storage, which *do* have a UUID which can be used as > CKA_ID. (Or maybe as CKA_LABEL since CKA_ID really SHOULD be the > pubkey hash, if we can manage that). So this is the actual problem: the TPM only stores private keys. The public key thing (can be simple, cert or something more fancy) isn't known to it. All pkcs11 searchers find the public key in the public objects and then look for the private key by id and label (this is what the standard recommends). The problem is that the label they use isn't going to be the UUID, so we need the private key to be labelled by what its public counterpart expects to use the TPM for arbitrary keys, like certificate private keys (or even gpg or ssh private keys). The UUID thing works for stuff that expects separate private and public key descriptions, like gnutls and openssl, but not for anything that uses the full pkcs11 protocol (like netscape). The second problem is that C_FindObject expects to be able to search all the keys. Unfortunately, neither the TPM nor Trousers has an enumeration protocol for TPM objects (we could hack trousers to do it, becuase it knows every key it inserted in an internal database, but there's no TSS API for it). Without enumeration, searching fails. Based on this, I think offline keys are a better format for pkcs11 because we have all the data present and can make it searchable. ssh, for instance, internally finds the private key using CKA_MODULUS and CKA_PUBLIC_EXPONENT, which we can't do if the key is inside the TPM, before exporting it by id (md5 fingerprint) and label (ssh comment). Plus there's the unsolved resource issue, of course: we can only fit about 10 keys in the TPM, whereas offline is infinitely expandable. My vision of how this would work is that we probably need a database of attributes. For certificates it's going to look something like the keyring gnome2 one, so there's no way to base any sophisticated pkcs11 implementation on something that doesn't have files at its core (regardless of where the TPM key resides). I'm agnostic over whether we have two files (one for the private and one for the public key) or a single one. I'm actually starting to think that a vanilla private key coupled with an attribute search on CKA_MODULUS,CKA_PUBLIC_EXPONENT is the best thing to do (except it won't work with TPM loaded keys). James > If you're talking about a PKCS#11 token which has its *own* storage > of wrapped keys, then sure — you can keep whatever metadata you like. > But you don't need that to be part of the PKCS#8 standard format. In > fact if you want this you're probably better off extending SoftHSM to > stored wrapped keys and use the TPM for operating them. smime.p7s Description: S/MIME cryptographic signature -- openssl-dev mailing list To unsubscribe: https://mta.openssl.org/mailman/listinfo/openssl-dev
Re: [openssl-dev] [RFC v2 0/2] Proposal for seamless handling of TPM based RSA keys in openssl
On Tue, 2016-12-13 at 22:28 +, David Woodhouse wrote: > On Tue, 2016-12-13 at 13:09 +, Dr. Stephen Henson wrote: > > The reason for that is that the PEM forms which contain > > the key algorithm in the PEM header were considered legacy types > > and new methods should use PKCS#8 instead. So there was no way to > > set legacy PEM decoders to discourage their use. > > > > In this case the reason is different: the header doesn't contain > > the algorithm type but a string which an ENGINE can handle. So it > > isn't a "legacy format" but a custom one. > > > > So if we wanted to go down this route all that is needed to get a > > form of this functionality is a function to set the PEM decoder in > > EVP_PKEY_ASN1_METHOD. > > I am not entirely averse to the idea of saying that TPM, at least as > of 2.0, should have a wrapped-key storage format which is based in > PKCS#8 rather than doing its own thing. So the proposal is to have a TPM specific value for PrivateKeyAlgorithm (which would have to be proposed as an OID) and use PrivateKeyInfo for the key? That could be made to work. The slight fly in the ointment that's worrying me is that I need a key format that works for pkcs#11 tokens as well. The problem here is that TPM keys don't have an id or a label and that's pretty much a requirement of using a pkcs#11 token, so the pkcs#11 code has to be able to set these attributes on the key files. I was originally thinking of putting them into the PEM header with a pkcs11- prefix. I suppose I can do the same with the attributes and some manufactured OID prefix with the CKA_ parameters we're interested in as a suffix but it's messy. James smime.p7s Description: S/MIME cryptographic signature -- openssl-dev mailing list To unsubscribe: https://mta.openssl.org/mailman/listinfo/openssl-dev
Re: [openssl-dev] [RFC v2 2/2] pem: load engine keys
On Fri, 2016-12-09 at 00:25 +, David Woodhouse wrote: > On Thu, 2016-12-08 at 16:22 -0800, James Bottomley wrote: > > > > I'm guessing you mean this: > > > > https://www.trustedcomputinggroup.org/wp-content/uploads/TSS_Versio > > n_1.2_Level_1_FINAL.pdf > > > > ? It still doesn't tell you who the expected parent of the key > > would be, which is the problem I'm currently trying to solve. > > Right, in S3.23 ("Portable Data") or thereabouts. And yes, it doesn't > indicate the parent key. As discussed, the TssBlob structure there is > fairly pointless which is presumably why the TPM ENGINE didn't use > it, and just dumped the actual blob (which I later put into an > OCTET_STRING in the PEM files, IIRC). > > I was hoping that the TPM 2.0 spec would fix that, maybe? Not far enough through it yet to be definitive, but I don't think so ... there's even more parent like seeds in it. James smime.p7s Description: S/MIME cryptographic signature -- openssl-dev mailing list To unsubscribe: https://mta.openssl.org/mailman/listinfo/openssl-dev
Re: [openssl-dev] [RFC v2 2/2] pem: load engine keys
On Thu, 2016-12-08 at 15:56 -0800, James Bottomley wrote: > On Thu, 2016-12-08 at 23:44 +, David Woodhouse wrote: > > On Tue, 2016-12-06 at 22:30 +0100, Richard Levitte wrote: > > > Oh > > > > > > I think I aired some thoughts on using PEM headers a very long > > > while > > > ago, but that never came into fruition, among others because I > > > ended > > > up doubting that it would be the best way in the long run. > > > > > > These days, the use of PEM headers is considered old and kinda > > > sorta > > > deprecated, even though OpenSSL still produces encrypted private > > > key > > > PEM files that uses headers for the encryption metadata. It > > > seems > > > that PKCS#8 is prefered "out there". > > > > > > So I have to wonder, is PEM really the right way to go for this? > > > Would it be just as possible to wrap a TSS key with a PKCS#8 > > > container, and use the associated attributes for the external > > > data? > > > Just a thought, though... I can't do more than throw around > > > ideas, > > > considering how little I know about TPM. > > > > I would definitely suggest that we *don't* want to do it with PEM > > headers. Just put the additional information into the binary ASN.1 > > structure. > > Which evil is lesser? If we put it in ASN.1 we'll be defining our > own > instead of using the TSS defined one. If we use headers, we can put > the extra data in them and use the TSS defined ASN.1 for the key > blob. > > > The 2.0 version of the TssBlob (from §3.23 of the 1.2 spec) should > > hopefully contain all the auxiliary information we need, without > > having to stick it in PEM headers. > > Which of the many specs is this? I'm guessing you mean this: https://www.trustedcomputinggroup.org/wp-content/uploads/TSS_Version_1.2_Level_1_FINAL.pdf ? It still doesn't tell you who the expected parent of the key would be, which is the problem I'm currently trying to solve. James smime.p7s Description: S/MIME cryptographic signature -- openssl-dev mailing list To unsubscribe: https://mta.openssl.org/mailman/listinfo/openssl-dev
Re: [openssl-dev] [RFC v2 2/2] pem: load engine keys
On Thu, 2016-12-08 at 23:44 +, David Woodhouse wrote: > On Tue, 2016-12-06 at 22:30 +0100, Richard Levitte wrote: > > Oh > > > > I think I aired some thoughts on using PEM headers a very long > > while > > ago, but that never came into fruition, among others because I > > ended > > up doubting that it would be the best way in the long run. > > > > These days, the use of PEM headers is considered old and kinda > > sorta > > deprecated, even though OpenSSL still produces encrypted private > > key > > PEM files that uses headers for the encryption metadata. It seems > > that PKCS#8 is prefered "out there". > > > > So I have to wonder, is PEM really the right way to go for this? > > Would it be just as possible to wrap a TSS key with a PKCS#8 > > container, and use the associated attributes for the external data? > > Just a thought, though... I can't do more than throw around ideas, > > considering how little I know about TPM. > > I would definitely suggest that we *don't* want to do it with PEM > headers. Just put the additional information into the binary ASN.1 > structure. Which evil is lesser? If we put it in ASN.1 we'll be defining our own instead of using the TSS defined one. If we use headers, we can put the extra data in them and use the TSS defined ASN.1 for the key blob. > The 2.0 version of the TssBlob (from §3.23 of the 1.2 spec) should > hopefully contain all the auxiliary information we need, without > having to stick it in PEM headers. Which of the many specs is this? James smime.p7s Description: S/MIME cryptographic signature -- openssl-dev mailing list To unsubscribe: https://mta.openssl.org/mailman/listinfo/openssl-dev
Re: [openssl-dev] [RFC v2 2/2] pem: load engine keys
On Tue, 2016-12-06 at 17:47 +0100, Richard Levitte wrote: > In message <1481042048.4406.14.ca...@hansenpartnership.com> on Tue, > 06 Dec 2016 08:34:08 -0800, James Bottomley < > james.bottom...@hansenpartnership.com> said: > > James.Bottomley> On Tue, 2016-12-06 at 15:12 +0100, Richard Levitte > wrote: > James.Bottomley> > In message < > 1480697558.2410.33.ca...@hansenpartnership.com> on Fri, > James.Bottomley> > 02 Dec 2016 08:52:38 -0800, James Bottomley < > James.Bottomley> > james.bottom...@hansenpartnership.com> said: > James.Bottomley> > > James.Bottomley> > When I made that argument, I hadn't thought and > felt things through > James.Bottomley> > entirely. Truth be told, I'm feeling very uneasy > handing over the > James.Bottomley> > reading and parsing of the PEM file to an engine. > However, handing > James.Bottomley> > over the decoded data and leaving it to the engine > to do something > James.Bottomley> > sensible with it, no issues at all. > James.Bottomley> > James.Bottomley> OK, can I pick on this a bit (I'll look at the store > stuff later and > James.Bottomley> reply after I've played with it)? What is it that > you imagine handing > James.Bottomley> to the engine? Some type of buffer that contains > the full PEM > James.Bottomley> representation? > > In my STORE branch, you will find this in > include/openssl/store_file.h: > > /* > * The try_decode function is called to check if the blob of data > can > * be used by this handler, and if it can, decodes it into a > supported > * OpenSSL and returns a STORE_INFO with the recorded data. > * Input: > *pem_name: If this blob comes from a PEM file, this > holds > * the PEM name. If it comes from another type > of > * file, this is NULL. > *blob: The blob of data to match with what this > handler > * can use. > *len: The length of the blob. > *handler_ctx: For a handler marked repeatable, this pointer > can > * be used to create a context for the handler. > IT IS > * THE HANDLER'S RESPONSIBILITY TO CREATE AND > DESTROY > * THIS CONTEXT APPROPRIATELY, i.e. create on > first call > * and destroy when about to return NULL. > *password_ui: Application UI method for getting a password. > *password_ui_data: > * Application data to be passed to password_ui > when > * it's called. > * Output: > *a STORE_INFO > */ > typedef STORE_INFO *(*STORE_FILE_try_decode_fn)(const char > *pem_name, > const unsigned > char *blob, > size_t len, > void > **handler_ctx, > const UI_METHOD > *password_ui, > void > *password_ui_data); > > This is the central function that tries to see if it can decode > whatever's thrown at it. As you can see, it gets handed the PEM name > if it's called as part of a PEM read. The |blob| is the decoded *and > decrypted* data. > > James.Bottomley> The reason I chose a BIO is that it's the basic > abstract data handler > James.Bottomley> for openssl. I can hand a buffer to the engine, > sure, but I'd need to > James.Bottomley> transform it to a BIO again (because it would need > PEM parsing and all > James.Bottomley> the PEM parsers speak BIOs), so it feels suboptimal. > > With a try_decode function, I really do not see why there's a need to > deal with the BIO... OK, I get what you want. There are two problems with this. The first is easy: I'm eventually going to need the BIO header as well because TPM2 keys are going to need to describe external things that aren't in the key representation (and even TPM1 keys might need to say who their parent key is). However, this is fixable by simply expanding your prototype above to have const char *pem_name and const char *pem_header ... is that OK? The next problem is that this is slightly harder simply to insert into the PEM code. The BIO parsing is done in PEM_bytes_read_bio() not PEM_read_bio_PrivateKey(). The easy way to cope with this would be to move PEM parsing into the ENGINE_find_engine_load_key() function and then hand the name, header, blob to the engine. The disadvantage of this is that we'll end up pulling the PEM apart twice: once in ENGINE_find_engine_load_key() and then again in PEM_bytes_read_bio(). Is this OK? If it is I can code up a v3. If not, I can think about how we might integrate this into PEM_bytes_read_bio(). James -- openssl-dev mailing list To unsubscribe: https://mta.openssl.org/mailman/listinfo/openssl-dev
Re: [openssl-dev] [RFC v2 2/2] pem: load engine keys
On Tue, 2016-12-06 at 15:12 +0100, Richard Levitte wrote: > In message <1480697558.2410.33.ca...@hansenpartnership.com> on Fri, > 02 Dec 2016 08:52:38 -0800, James Bottomley < > james.bottom...@hansenpartnership.com> said: > > James.Bottomley> On Thu, 2016-12-01 at 09:30 +0100, Richard Levitte > wrote: > James.Bottomley> > > James.Bottomley> > James Bottomley < > james.bottom...@hansenpartnership.com> skrev: (1 > James.Bottomley> > december 2016 07:36:26 CET) > James.Bottomley> > > On Thu, 2016-12-01 at 01:38 +0100, Richard > Levitte wrote: > James.Bottomley> > > > > James.Bottomley> > > > James Bottomley < > james.bottom...@hansenpartnership.com> skrev: (1 > James.Bottomley> > > > december 2016 00:42:09 CET) > James.Bottomley> [...] > James.Bottomley> > > > > On Thu, 2016-12-01 at 00:22 +0100, Richard > Levitte wrote: > James.Bottomley> > > > > > Generally speaking, I am unsure about your > solution. It seems > James.Bottomley> > > > > > like hack to fit a specific case where > something more general > James.Bottomley> > > > > > could be of greater service to others as > well. > James.Bottomley> > > > > > James.Bottomley> > > > > Well, the more adaptable patch set was the > previous one that > James.Bottomley> > > > > overloaded the meaning of key_id. This one > has a specific bio > James.Bottomley> > > > > mechanism for loading PEM files, so it only > really works for > James.Bottomley> > > > > engines that have PEM representable unloaded > keys (which, to be > James.Bottomley> > > > > fair, is almost all of them, since even the > USB crypto keys > James.Bottomley> > > > > have a wrapped format). > James.Bottomley> > > > > > James.Bottomley> > > > > I've tried to make it as generic as > possible, but I am > James.Bottomley> > > > > conditioned to think to my use case: TPM > keys. If you give an > James.Bottomley> > > > > example of another use case, it will help me > see where it > James.Bottomley> > > > > should be more generic. > James.Bottomley> > > > > James.Bottomley> > > > Among other things, I'd rather not encourage > an API that > James.Bottomley> > > > inherently makes the engine<->libcrypto tie > even tighter. Also, > James.Bottomley> > > > it puts a requirement on the engine to parse > PEM, which is > James.Bottomley> > > > unnecessary. > James.Bottomley> > James.Bottomley> Actually, I missed this initially. This is > definitely not a > James.Bottomley> requirement: engines that wish to parse PEM keys may > do so, but an > James.Bottomley> engine that doesn't simply doesn't implement the > callback. Only > James.Bottomley> engines that are loaded from the configuration file > actually get asked > James.Bottomley> if they understand the key, and then only if they > supply the callback, > James.Bottomley> so this is a decision on which engines to is made by > the admin or > James.Bottomley> packager (and the engine builder, who decides > whether to implement or > James.Bottomley> not). > > When I made that argument, I hadn't thought and felt things through > entirely. Truth be told, I'm feeling very uneasy handing over the > reading and parsing of the PEM file to an engine. However, handing > over the decoded data and leaving it to the engine to do something > sensible with it, no issues at all. OK, can I pick on this a bit (I'll look at the store stuff later and reply after I've played with it)? What is it that you imagine handing to the engine? Some type of buffer that contains the full PEM representation? The reason I chose a BIO is that it's the basic abstract data handler for openssl. I can hand a buffer to the engine, sure, but I'd need to transform it to a BIO again (because it would need PEM parsing and all the PEM parsers speak BIOs), so it feels suboptimal. James -- openssl-dev mailing list To unsubscribe: https://mta.openssl.org/mailman/listinfo/openssl-dev
Re: [openssl-dev] [RFC v2 2/2] pem: load engine keys
On Thu, 2016-12-01 at 09:30 +0100, Richard Levitte wrote: > > James Bottomley skrev: (1 > december 2016 07:36:26 CET) > > On Thu, 2016-12-01 at 01:38 +0100, Richard Levitte wrote: > > > > > > James Bottomley skrev: (1 > > > december 2016 00:42:09 CET) [...] > > > > On Thu, 2016-12-01 at 00:22 +0100, Richard Levitte wrote: > > > > > Generally speaking, I am unsure about your solution. It seems > > > > > like hack to fit a specific case where something more general > > > > > could be of greater service to others as well. > > > > > > > > Well, the more adaptable patch set was the previous one that > > > > overloaded the meaning of key_id. This one has a specific bio > > > > mechanism for loading PEM files, so it only really works for > > > > engines that have PEM representable unloaded keys (which, to be > > > > fair, is almost all of them, since even the USB crypto keys > > > > have a wrapped format). > > > > > > > > I've tried to make it as generic as possible, but I am > > > > conditioned to think to my use case: TPM keys. If you give an > > > > example of another use case, it will help me see where it > > > > should be more generic. > > > > > > Among other things, I'd rather not encourage an API that > > > inherently makes the engine<->libcrypto tie even tighter. Also, > > > it puts a requirement on the engine to parse PEM, which is > > > unnecessary. Actually, I missed this initially. This is definitely not a requirement: engines that wish to parse PEM keys may do so, but an engine that doesn't simply doesn't implement the callback. Only engines that are loaded from the configuration file actually get asked if they understand the key, and then only if they supply the callback, so this is a decision on which engines to is made by the admin or packager (and the engine builder, who decides whether to implement or not). > > > Also, we already have thoughts on loading keys by uri references, > > > and there may be new ideas and formats coming in the future. All > > > this is tied together and solving it one small hack at a time is > > > sub-optimal in the long run. > > > > > > I'll repeat myself again, please have a look at the STORE stuff > > > I'm working on. TPM files could very well serve as a first use > > > case. > > > > That's this new pull request: > > > > https://github.com/openssl/openssl/pull/2011/files > > Yes. > > > Just so I understand you, you mean register a store handler from > > the engine for the TPM BLOB PEM files so that a reference to the > > file via the store can use the PEM file as an EVP_PKEY? > > Essentially, yes. > > > That will work, I'm just not clear from the current pull request > > how the store would be integrated with the existing PEM file > > handler > > ... > > Will every application have to be modified to use the new store, or > > will you hook it like I did for the engine keys? > > Generally speaking, I was thinking that applications would move to > use the STORE API. > > > The think I'm looking for is to have a TPM PEM key file just work > > in place of a standard RSA private key file. > > I get your point. That could be med as a call after the > PEM_bytes_read_bio call. At that point, the necessary data for an > internal store loading are available. It's still a hack, but if you > must... If I summarise the arguments about self identifying files from the v1 thread: 1. We agreed that usability is greatly enhanced if openssl simply loads a key when presented with the file/uri etc. without the user having to specify what the format of a key is 2. For PEM files, we believe this is easy because the guards uniquely identify the file format, so whatever key the application needs, we can verify is contained in the thing presented 3. THere was more debate on the files that aren't fully self describing, like DER. The argument was that the DER structure is usually unique enough, so we could do this, but there were reservations. 4. I thought there was agreement that we could move forwards with the PEM bit because it was uncontroversial The current PEM key loading code is already hooked for PKCS8, to make the above a reality, we should hook it for pkcs12 as well. Once you have the store code, I believe it should be hooked for this as well. In this scenario, I don't quite see why it's not a hack to hook for pkcs8 (and presumably 12) but it is a hack to hook for engines and store. If we agree on DER, the ideal world becomes all apps simply use OPENSSL_load_privkey() and no-one needs to worry about format for key loading because any reasonable format just works. James -- openssl-dev mailing list To unsubscribe: https://mta.openssl.org/mailman/listinfo/openssl-dev
Re: [openssl-dev] [RFC v2 0/2] Proposal for seamless handling of TPM based RSA keys in openssl
On Thu, 2016-12-01 at 12:49 +0100, Nikos Mavrogiannopoulos wrote: > On Wed, 2016-11-30 at 13:59 -0800, James Bottomley wrote: > > > > > The point here is that because there's a pem file > > > representation of the > > > > key, it can be used anywhere a PEM file can be *without* > > > having > > > to tell > > > > openssl what the engine is (the PEM guards being unique to > > > the > > > key > > > > type). > > > > > > Well, I think I can see your point (except for the above > > > question), but frankly I don’t like this approach very much. > > > > It's already a mechanism used by gnutls to load TPM keys, so it > > makes sense from a compatibility point of view that it should just > > work for openssl as well. It doesn't preclude using a pkcs11 token > > approach as well, it's just a different mechanism for handling > > keys. > > Note that gnutls' mechanism relies on the "tpmkey:" URLs to load > them, rather than loading via any other PEM mechanism. The URL > approach has the advantage that it provides a uniformity in handling > similar to PKCS#11 URLs (and it wouldn't matter whether these keys > are in file, in the TPM itself or in some other OS storage area - you > specify them all the same). > > However, neither of URLs or file loading would survive the TPM 2.0 > thing. Actually, I believe it will. The main difference is that TPM2 has multiple SRKs so you need to know which one, plus TSS2 will be different from TSS1 so they can't be handled by the same engine: so the format will have a new guard (TSS2 KEY BLOB probably) and the multiple root can be coped with by specifying the root as a PEM parameter). Incidentally, a similar problem does exist in TPM1: although everything chains up to a single SRK, you can have multiple sub SRK storage keys to which the keys are wrapped. Right at the moment, the current openssl_tpm_engine doesn't contemplate this possibility, but I'm thinking of extending it to do so, because it's useful when doing TPM tenancy (cloud container use case). > Most likely (and hopefully) the latter keys will be handled over > PKCS#11 rather than directly. I have reservations about scaling pkcs11 into a multi-tenant environment, but I agree, in principle it is possible. I'm looking at trying to do it better for TPM now (well, it's the next thing to get to on my list). James -- openssl-dev mailing list To unsubscribe: https://mta.openssl.org/mailman/listinfo/openssl-dev
Re: [openssl-dev] [RFC v2 2/2] pem: load engine keys
On Thu, 2016-12-01 at 01:38 +0100, Richard Levitte wrote: > > James Bottomley skrev: (1 > december 2016 00:42:09 CET) > > On Thu, 2016-12-01 at 00:22 +0100, Richard Levitte wrote: > > > This patch doesn't fit the rest... > > > > I'm not quite sure I follow why. > > It casts bp to const char *. That was for your earlier > implementation, wasn't it? It doesn't fit the latest incarnation of > your API. Good catch: a leftover I missed the warning for in the spray of other compile information. Apparently the debug-linux-x86_64 target doesn't have a -Werror ... I've added it so I should pick a problem like this up easily. > > > Generally speaking, I am unsure about your solution. It seems > > > like hack to fit a specific case where something more general > > > could be of greater service to others as well. > > > > Well, the more adaptable patch set was the previous one that > > overloaded the meaning of key_id. This one has a specific bio > > mechanism for loading PEM files, so it only really works for > > engines that have PEM representable unloaded keys (which, to be > > fair, is almost all of them, since even the USB crypto keys have a > > wrapped format). > > > > I've tried to make it as generic as possible, but I am conditioned > > to think to my use case: TPM keys. If you give an example of > > another use case, it will help me see where it should be more > > generic. > > Among other things, I'd rather not encourage an API that inherently > makes the engine<->libcrypto tie even tighter. Also, it puts a > requirement on the engine to parse PEM, which is unnecessary. > > Also, we already have thoughts on loading keys by uri references, and > there may be new ideas and formats coming in the future. All this is > tied together and solving it one small hack at a time is sub-optimal > in the long run. > > I'll repeat myself again, please have a look at the STORE stuff I'm > working on. TPM files could very well serve as a first use case. That's this new pull request: https://github.com/openssl/openssl/pull/2011/files ? Just so I understand you, you mean register a store handler from the engine for the TPM BLOB PEM files so that a reference to the file via the store can use the PEM file as an EVP_PKEY? That will work, I'm just not clear from the current pull request how the store would be integrated with the existing PEM file handler ... Will every application have to be modified to use the new store, or will you hook it like I did for the engine keys? The think I'm looking for is to have a TPM PEM key file just work in place of a standard RSA private key file. James > > James > > > > > > > Cheers > > > Richard > > > > > > On November 30, 2016 4:27:49 PM GMT+01:00, James Bottomley < > > > james.bottom...@hansenpartnership.com> wrote: > > > > Before trying to process the PEM file, hand it to each of the > > > > loaded > > > > engines to see if they recognise the PEM guards. This uses the > > > > new > > > > bio based load key callback, so the engine must be loaded and > > > > implement this callback to be considered. > > > > > > > > Signed-off-by: James Bottomley > > > > --- > > > > crypto/pem/pem_pkey.c | 4 > > > > 1 file changed, 4 insertions(+) > > > > > > > > diff --git a/crypto/pem/pem_pkey.c b/crypto/pem/pem_pkey.c > > > > index 04d6319..e3737f0 100644 > > > > --- a/crypto/pem/pem_pkey.c > > > > +++ b/crypto/pem/pem_pkey.c > > > > @@ -85,6 +85,10 @@ EVP_PKEY *PEM_read_bio_PrivateKey(BIO *bp, > > > > EVP_PKEY > > > > **x, pem_password_cb *cb, > > > > int slen; > > > > EVP_PKEY *ret = NULL; > > > > > > > > +/* first check to see if an engine can load the PEM */ > > > > +if (ENGINE_find_engine_load_key(NULL, &ret, (const char > > > > *)bp, > > > > cb, > > > > u) == 1) > > > > +return ret; > > > > + > > > > if (!PEM_bytes_read_bio(&data, &len, &nm, PEM_STRING_EVP_PKEY, > > > > bp, > > > > cb, > > > > u)) > > > > return NULL; > > > > p = data; > > > > > > -- > > > levi...@openssl.org > > -- > Sent from my Android device with K-9 Mail. Please excuse my brevity. -- openssl-dev mailing list To unsubscribe: https://mta.openssl.org/mailman/listinfo/openssl-dev
Re: [openssl-dev] [RFC v2 2/2] pem: load engine keys
On Thu, 2016-12-01 at 00:22 +0100, Richard Levitte wrote: > This patch doesn't fit the rest... I'm not quite sure I follow why. To allow engines to load PEM encoded engine keys in place of machine processed ones, the hook into the loader has to be in somewhere. This seems to be the most generic place to put the hook. > Generally speaking, I am unsure about your solution. It seems like > hack to fit a specific case where something more general could be of > greater service to others as well. Well, the more adaptable patch set was the previous one that overloaded the meaning of key_id. This one has a specific bio mechanism for loading PEM files, so it only really works for engines that have PEM representable unloaded keys (which, to be fair, is almost all of them, since even the USB crypto keys have a wrapped format). I've tried to make it as generic as possible, but I am conditioned to think to my use case: TPM keys. If you give an example of another use case, it will help me see where it should be more generic. James > Cheers > Richard > > On November 30, 2016 4:27:49 PM GMT+01:00, James Bottomley < > james.bottom...@hansenpartnership.com> wrote: > > Before trying to process the PEM file, hand it to each of the > > loaded > > engines to see if they recognise the PEM guards. This uses the new > > bio based load key callback, so the engine must be loaded and > > implement this callback to be considered. > > > > Signed-off-by: James Bottomley > > --- > > crypto/pem/pem_pkey.c | 4 > > 1 file changed, 4 insertions(+) > > > > diff --git a/crypto/pem/pem_pkey.c b/crypto/pem/pem_pkey.c > > index 04d6319..e3737f0 100644 > > --- a/crypto/pem/pem_pkey.c > > +++ b/crypto/pem/pem_pkey.c > > @@ -85,6 +85,10 @@ EVP_PKEY *PEM_read_bio_PrivateKey(BIO *bp, > > EVP_PKEY > > **x, pem_password_cb *cb, > > int slen; > > EVP_PKEY *ret = NULL; > > > > +/* first check to see if an engine can load the PEM */ > > +if (ENGINE_find_engine_load_key(NULL, &ret, (const char *)bp, > > cb, > > u) == 1) > > +return ret; > > + > > if (!PEM_bytes_read_bio(&data, &len, &nm, PEM_STRING_EVP_PKEY, bp, > > cb, > > u)) > > return NULL; > > p = data; > > -- > levi...@openssl.org -- openssl-dev mailing list To unsubscribe: https://mta.openssl.org/mailman/listinfo/openssl-dev
Re: [openssl-dev] [RFC v2 0/2] Proposal for seamless handling of TPM based RSA keys in openssl
On Wed, 2016-11-30 at 21:41 +, Blumenthal, Uri - 0553 - MITLL wrote: > >> So why is it better to say “…engine –key > /some/weird/path/weird > >> -file.pem” than “…engine –key pkcs11:id=02” (or such)? > > > > There appears to be some confusion here. pkcs11 is a > representation > > for defined tokens. > > Well, I did not mean *specifically* pkcs11 – just as an example of > something that currently works. > > > > However, for TPM, there's also file representation > > of an unloaded key (it has to be parented or "wrapped" to one > of the > > loaded storage keys, usually the SRK). > > So this PEM wrapping is needed just to load keys into TPM? How do you > refer to those keys when they are already loaded? The keys are TPM volatile, so they're effectively unloaded as soon as you close the TPM connection. The engine code to use them is here https://sourceforge.net/p/trousers/openssl_tpm_engine the TPM connection is from engine init to engine finish and once the key is loaded, it stays in the TPM until engine finish. create_tpm_key is what takes a standard RSA key and wraps it to the SRK as a volatile key for the TPM. > > > The point here is that because there's a pem file > representation of the > > key, it can be used anywhere a PEM file can be *without* having > to tell > > openssl what the engine is (the PEM guards being unique to the > key > > type). > > Well, I think I can see your point (except for the above question), > but frankly I don’t like this approach very much. It's already a mechanism used by gnutls to load TPM keys, so it makes sense from a compatibility point of view that it should just work for openssl as well. It doesn't preclude using a pkcs11 token approach as well, it's just a different mechanism for handling keys. I like it because it's easier than trying to set up and use TPM token, which seems to be very hard without admin privileges (the PEM file approach can be used by any user of the system provided the SRK has a well known authority). James smime.p7s Description: S/MIME cryptographic signature -- openssl-dev mailing list To unsubscribe: https://mta.openssl.org/mailman/listinfo/openssl-dev
Re: [openssl-dev] [RFC v2 0/2] Proposal for seamless handling of TPM based RSA keys in openssl
On Wed, 2016-11-30 at 21:18 +, Blumenthal, Uri - 0553 - MITLL wrote: > On 11/30/16, 10:24 AM, "openssl-dev on behalf of James Bottomley" < > openssl-dev-boun...@openssl.org on behalf of > james.bottom...@hansenpartnership.com> wrote: > > > One of the principle problems of using TPM based keys is that > there's > > no easy way of integrating them with standard file based keys. > > Why should token- and/or TPM-based keys be integrated with file-based > keys? OpenSSL and its engines need/should accept URI pointing at the > keys. Pointing them at files containing some proprietary reference to > keys that are kept in hardware does not seem to make sense. > > So why is it better to say “…engine –key /some/weird/path/weird > -file.pem” than “…engine –key pkcs11:id=02” (or such)? There appears to be some confusion here. pkcs11 is a representation for defined tokens. However, for TPM, there's also file representation of an unloaded key (it has to be parented or "wrapped" to one of the loaded storage keys, usually the SRK). There is no URI reference (other than a file one) because any key so described may exist only in the file and don't have to be part of the tpm token infrastructure. To make use of it, the engine first has to load the key into the TPM. It's actually a simpler way of handling keys than loading them into the TPM pkcs11 token infrastructure and naming them by slot and key The point here is that because there's a pem file representation of the key, it can be used anywhere a PEM file can be *without* having to tell openssl what the engine is (the PEM guards being unique to the key type). James smime.p7s Description: S/MIME cryptographic signature -- openssl-dev mailing list To unsubscribe: https://mta.openssl.org/mailman/listinfo/openssl-dev
Re: [openssl-dev] [RFC v2 2/2] pem: load engine keys
On Wed, 2016-11-30 at 19:32 +, Salz, Rich wrote: > > OK, so where is the foundation charter and who are your lawyers? > > Wow, this seems to have taken a turn to the unfriendly. I apologize > if I added to that. Sometimes a smiley doesn't wipe out all bad > impressions. No, it's standard if you insist on the CLA route: If you sign a CLA to an organization, you have to understand what the organization does before you understand what you're actually committing to: the actual commitment isn't within the four corners of the CLA. Your current ICLA gives effectively an unlimited perpetual licence to do anything with regard to sublicensing so the scope of that grant is actually governed by the bylaws and restrictions of the foundation itself because it is the grant recipient. For instance, the old OpenStack ICLA was fairly similar to yours so you had to dig into their bylaws to understand what they were actually committing to do with the code (basically sublicense it to all comers under ASL-2). The structure of the organisation matters a lot: unlimited grant to a corporate entity under a CLA is usually a bad idea because they often have nefarious plans to take your code private via a dual licence, or they might mean well, but their intentions become nullified if they get taken over. Foundations are usually better because their charter often restricts what they can actually do with the code and what happens to the grant in the event of dissolution or takeover, which is why reading and understanding the charter (and possibly the bylaws) is important. Usually I don't have to ask, all of this is simply available on the web most of the time. It's just the openssl foundation doesn't appear to have any of this online. I suspect IBM will need to sign a CCLA ... they'll definitely need to know who your lawyers are. > The OpenSSL Software Foundation is incorporated in the the state of > Delaware, United States, as a non-profit corporation. It does not > qualify as a tax-exempt charitable organisation under Section > 501(c)(3) of the U.S. Internal Revenue Code. You can email > i...@opensslfoundation.org with questions. > But do note that openssl open source project itself is not governed > by those entities, but rather by the collection of individuals known > as the development team. You can find more information by clicking > on the "policies" and "community" tab on the website. I did check those links ... they don't have any governance information about the actual openssl foundation that I can find. James -- openssl-dev mailing list To unsubscribe: https://mta.openssl.org/mailman/listinfo/openssl-dev
Re: [openssl-dev] [RFC v2 2/2] pem: load engine keys
On Wed, 2016-11-30 at 17:59 +, Salz, Rich wrote: > > > Plus the DCO is industry best practice: even OpenStack is adopting > > it after a > > long struggle. > > Great. Good for them. > > This is what we're doing. > > :) OK, so where is the foundation charter and who are your lawyers? James -- openssl-dev mailing list To unsubscribe: https://mta.openssl.org/mailman/listinfo/openssl-dev
Re: [openssl-dev] [RFC v2 2/2] pem: load engine keys
On Wed, 2016-11-30 at 16:04 +, Salz, Rich wrote: > > Groan ... since you're changing licences, I don't suppose you'd > > consider moving to a DCO model. > > Sorry, no. Legal advice and best practices. Interesting: whose legal advice? I assumed you were talking to the SFLC and I thought they were mostly pre-programmed not to recommend CLAs after their FSF experience. I'm asking professionally because the knee jerk reaction of most lawyers is to recommend a CLA and there's a group programme (run by the LF) to help them kick the habit. Plus the DCO is industry best practice: even OpenStack is adopting it after a long struggle. James -- openssl-dev mailing list To unsubscribe: https://mta.openssl.org/mailman/listinfo/openssl-dev
Re: [openssl-dev] [RFC v2 2/2] pem: load engine keys
> Thanks for working to improve openssl. You're welcome. > It is probably easier for you to do a GitHub pull request and then > have discussion here, pointing to that PR. Actually, being a kernel developer, email is far easier. I'll send a pull request when everyone's OK with the mechanism, plus it will need tests and other things. > And also, before any of this code could be used, we'll need the > appropriate CLA. Groan ... since you're changing licences, I don't suppose you'd consider moving to a DCO model. It's a whole lot less bureaucratic and much easier to keep track of. James -- openssl-dev mailing list To unsubscribe: https://mta.openssl.org/mailman/listinfo/openssl-dev
[openssl-dev] [PATCH] openssl tpm engine: add new openssl bio method for seamless loading of tpm keys
Permits this engine to be used as part of the openssl pem routines for loading TPM based keys. To use this, the tpm engine must be preloaded via the openssl.cnf file Signed-off-by: James Bottomley --- configure.in | 2 + e_tpm.c | 139 +++ 2 files changed, 113 insertions(+), 28 deletions(-) diff --git a/configure.in b/configure.in index d07617d..4e2eff9 100644 --- a/configure.in +++ b/configure.in @@ -51,6 +51,8 @@ AC_PROG_LIBTOOL CFLAGS="$CFLAGS -Wall" AC_SUBST(CFLAGS) +AC_CHECK_LIB(crypto, ENGINE_find_engine_load_key, [AC_DEFINE(HAVE_ENGINE_FIND_ENGINE_LOAD_KEY)]) + AC_OUTPUT(Makefile test/Makefile) echo "CFLAGS=$CFLAGS" diff --git a/e_tpm.c b/e_tpm.c index 3e20f8e..40ed4da 100644 --- a/e_tpm.c +++ b/e_tpm.c @@ -43,13 +43,20 @@ #ifndef OPENSSL_NO_HW #ifndef OPENSSL_NO_HW_TPM +struct tpm_ui { +UI_METHOD *ui_method; +pem_password_cb *pem_cb; +}; + /* engine specific functions */ static int tpm_engine_destroy(ENGINE *); static int tpm_engine_init(ENGINE *); static int tpm_engine_finish(ENGINE *); static int tpm_engine_ctrl(ENGINE *, int, long, void *, void (*)()); static EVP_PKEY *tpm_engine_load_key(ENGINE *, const char *, UI_METHOD *, void *); -static char *tpm_engine_get_auth(UI_METHOD *, char *, int, char *, void *); +/* note unused unless HAVE_ENGINE_FIND_ENGINE_LOAD_KEY is defined */ +static int tpm_engine_load_key_bio(ENGINE *, EVP_PKEY **, BIO *, pem_password_cb *, void *) __attribute__((unused)); +static char *tpm_engine_get_auth(struct tpm_ui *, char *, int, char *, void *); #ifndef OPENSSL_NO_RSA /* rsa functions */ @@ -212,6 +219,9 @@ static int bind_helper(ENGINE * e) !ENGINE_set_ctrl_function(e, tpm_engine_ctrl) || !ENGINE_set_load_pubkey_function(e, tpm_engine_load_key) || !ENGINE_set_load_privkey_function(e, tpm_engine_load_key) || +#ifdef HAVE_ENGINE_FIND_ENGINE_LOAD_KEY +!ENGINE_set_load_privkey_bio_function(e, tpm_engine_load_key_bio) || +#endif !ENGINE_set_cmd_defns(e, tpm_cmd_defns)) return 0; @@ -244,7 +254,7 @@ void ENGINE_load_tpm(void) ERR_clear_error(); } -int tpm_load_srk(UI_METHOD *ui, void *cb_data) +int tpm_load_srk(struct tpm_ui *ui, void *cb_data) { TSS_RESULT result; UINT32 authusage; @@ -451,8 +461,9 @@ err: return 0; } -static char *tpm_engine_get_auth(UI_METHOD *ui_method, char *auth, int maxlen, -char *input_string, void *cb_data) +static char *tpm_engine_get_auth_ui(UI_METHOD *ui_method, char *auth, + int maxlen, char *input_string, + void *cb_data) { UI *ui; @@ -479,6 +490,30 @@ static char *tpm_engine_get_auth(UI_METHOD *ui_method, char *auth, int maxlen, return auth; } +static char *tpm_engine_get_auth_pem(pem_password_cb *pem_cb, char *auth, + int maxlen, char *input_string, + void *cb_data) +{ + EVP_set_pw_prompt(input_string); + if (!pem_cb) + pem_cb = PEM_def_callback; + pem_cb(auth, maxlen, 0, cb_data); + EVP_set_pw_prompt(NULL); + + return auth; +} + +static char *tpm_engine_get_auth(struct tpm_ui *ui, char *auth, + int maxlen, char *input_string, void *cb_data) +{ + if (ui->ui_method) + return tpm_engine_get_auth_ui(ui->ui_method, auth, maxlen, + input_string, cb_data); + else + return tpm_engine_get_auth_pem(ui->pem_cb, auth, maxlen, + input_string, cb_data); +} + static int tpm_engine_finish(ENGINE * e) { DBG("%s", __FUNCTION__); @@ -575,8 +610,9 @@ int fill_out_rsa_object(RSA *rsa, TSS_HKEY hKey) return 1; } -static EVP_PKEY *tpm_engine_load_key(ENGINE *e, const char *key_id, -UI_METHOD *ui, void *cb_data) +static int tpm_engine_load_key_core(ENGINE *e, EVP_PKEY **ppkey, + const char *key_id, BIO *bio, + struct tpm_ui *ui, void *cb_data) { ASN1_OCTET_STRING *blobstr; TSS_HKEY hKey; @@ -589,39 +625,57 @@ static EVP_PKEY *tpm_engine_load_key(ENGINE *e, const char *key_id, DBG("%s", __FUNCTION__); - if (!key_id) { + if (!key_id && !bio) { TSSerr(TPM_F_TPM_ENGINE_LOAD_KEY, ERR_R_PASSED_NULL_PARAMETER); - return NULL; - } - - if (!tpm_load_srk(ui, cb_data)) { - TSSerr(TPM_F_TPM_ENGINE_LOAD_KEY, TPM_R_SRK_LOAD_FAILED); - return NULL; + return 0; } - if ((bf = BIO_new_file(key_id, "r")) == NULL) { - TSSerr(TPM
[openssl-dev] [RFC v2 2/2] pem: load engine keys
Before trying to process the PEM file, hand it to each of the loaded engines to see if they recognise the PEM guards. This uses the new bio based load key callback, so the engine must be loaded and implement this callback to be considered. Signed-off-by: James Bottomley --- crypto/pem/pem_pkey.c | 4 1 file changed, 4 insertions(+) diff --git a/crypto/pem/pem_pkey.c b/crypto/pem/pem_pkey.c index 04d6319..e3737f0 100644 --- a/crypto/pem/pem_pkey.c +++ b/crypto/pem/pem_pkey.c @@ -85,6 +85,10 @@ EVP_PKEY *PEM_read_bio_PrivateKey(BIO *bp, EVP_PKEY **x, pem_password_cb *cb, int slen; EVP_PKEY *ret = NULL; +/* first check to see if an engine can load the PEM */ +if (ENGINE_find_engine_load_key(NULL, &ret, (const char *)bp, cb, u) == 1) +return ret; + if (!PEM_bytes_read_bio(&data, &len, &nm, PEM_STRING_EVP_PKEY, bp, cb, u)) return NULL; p = data; -- 2.6.6 -- openssl-dev mailing list To unsubscribe: https://mta.openssl.org/mailman/listinfo/openssl-dev
[openssl-dev] [RFC v2 1/2] engine: add new bio based method for loading engine keys
Some engines have a PEM format for their keys, so add a mechanism whereby these keys can be read in to EVP_PKEY structures backed by the engine methods. The expectation is that each engine that wants to use this will define its own unique guard tags for the PEM file. Signed-off-by: James Bottomley --- crypto/engine/eng_int.h | 1 + crypto/engine/eng_pkey.c | 38 ++ crypto/engine/engine.h | 17 + 3 files changed, 56 insertions(+) diff --git a/crypto/engine/eng_int.h b/crypto/engine/eng_int.h index 46f163b..1d182c8 100644 --- a/crypto/engine/eng_int.h +++ b/crypto/engine/eng_int.h @@ -197,6 +197,7 @@ struct engine_st { ENGINE_CTRL_FUNC_PTR ctrl; ENGINE_LOAD_KEY_PTR load_privkey; ENGINE_LOAD_KEY_PTR load_pubkey; +ENGINE_LOAD_KEY_BIO_PTR load_privkey_bio; ENGINE_SSL_CLIENT_CERT_PTR load_ssl_client_cert; const ENGINE_CMD_DEFN *cmd_defns; int flags; diff --git a/crypto/engine/eng_pkey.c b/crypto/engine/eng_pkey.c index 23580d9..0eb7d6e 100644 --- a/crypto/engine/eng_pkey.c +++ b/crypto/engine/eng_pkey.c @@ -64,6 +64,13 @@ int ENGINE_set_load_privkey_function(ENGINE *e, return 1; } +int ENGINE_set_load_privkey_bio_function(ENGINE *e, +ENGINE_LOAD_KEY_BIO_PTR load_f) +{ +e->load_privkey_bio = load_f; +return 1; +} + int ENGINE_set_load_pubkey_function(ENGINE *e, ENGINE_LOAD_KEY_PTR loadpub_f) { e->load_pubkey = loadpub_f; @@ -88,6 +95,11 @@ ENGINE_LOAD_KEY_PTR ENGINE_get_load_pubkey_function(const ENGINE *e) return e->load_pubkey; } +ENGINE_LOAD_KEY_BIO_PTR ENGINE_get_load_privkey_bio_function(const ENGINE *e) +{ +return e->load_privkey_bio; +} + ENGINE_SSL_CLIENT_CERT_PTR ENGINE_get_ssl_client_cert_function(const ENGINE *e) { @@ -184,3 +196,29 @@ int ENGINE_load_ssl_client_cert(ENGINE *e, SSL *s, return e->load_ssl_client_cert(e, s, ca_dn, pcert, ppkey, pother, ui_method, callback_data); } + +int ENGINE_find_engine_load_key(ENGINE **e, EVP_PKEY **pkey, BIO *bio, +pem_password_cb *cb, void *cb_data) +{ +ENGINE *ep; +int ret = 0; + +for (ep = ENGINE_get_first(); ep != NULL; ep = ENGINE_get_next(ep)) { +if (!ep->load_privkey_bio) +continue; +if (ep->load_privkey_bio(ep, pkey, bio, cb, cb_data) == 1) { +ret = 1; +break; +} + + /* reset the bio and clear any error */ + (void)BIO_reset(bio); + ERR_clear_error(); +} +if (e) +*e = ep; +else if (ep) +ENGINE_free(ep); + +return ret; +} diff --git a/crypto/engine/engine.h b/crypto/engine/engine.h index bd7b591..022be41 100644 --- a/crypto/engine/engine.h +++ b/crypto/engine/engine.h @@ -97,6 +97,7 @@ # include # include +# include #ifdef __cplusplus extern "C" { @@ -338,6 +339,11 @@ typedef int (*ENGINE_CTRL_FUNC_PTR) (ENGINE *, int, long, void *, typedef EVP_PKEY *(*ENGINE_LOAD_KEY_PTR)(ENGINE *, const char *, UI_METHOD *ui_method, void *callback_data); + +/* Load key from bio if engine recognises the pem guards */ +typedef int (*ENGINE_LOAD_KEY_BIO_PTR)(ENGINE *, EVP_PKEY **, BIO *, + pem_password_cb *pwd_callback, + void *callback_data); typedef int (*ENGINE_SSL_CLIENT_CERT_PTR) (ENGINE *, SSL *ssl, STACK_OF(X509_NAME) *ca_dn, X509 **pcert, EVP_PKEY **pkey, @@ -565,6 +571,8 @@ int ENGINE_set_finish_function(ENGINE *e, ENGINE_GEN_INT_FUNC_PTR finish_f); int ENGINE_set_ctrl_function(ENGINE *e, ENGINE_CTRL_FUNC_PTR ctrl_f); int ENGINE_set_load_privkey_function(ENGINE *e, ENGINE_LOAD_KEY_PTR loadpriv_f); +int ENGINE_set_load_privkey_bio_function(ENGINE *e, +ENGINE_LOAD_KEY_BIO_PTR loadpriv_f); int ENGINE_set_load_pubkey_function(ENGINE *e, ENGINE_LOAD_KEY_PTR loadpub_f); int ENGINE_set_load_ssl_client_cert_function(ENGINE *e, ENGINE_SSL_CLIENT_CERT_PTR @@ -611,6 +619,7 @@ ENGINE_GEN_INT_FUNC_PTR ENGINE_get_finish_function(const ENGINE *e); ENGINE_CTRL_FUNC_PTR ENGINE_get_ctrl_function(const ENGINE *e); ENGINE_LOAD_KEY_PTR ENGINE_get_load_privkey_function(const ENGINE *e); ENGINE_LOAD_KEY_PTR ENGINE_get_load_pubkey_function(const ENGINE *e); +ENGINE_LOAD_KEY_BIO_PTR ENGINE_get_load_privkey_bio_function(const ENGINE *e); ENGINE_SSL_CLIENT_CERT_PTR ENGINE_get_ssl_client_cert_function(const ENGINE *e); ENGINE_CIPHERS_PTR ENGINE_get_ciphers(const ENGIN
[openssl-dev] [RFC v2 0/2] Proposal for seamless handling of TPM based RSA keys in openssl
One of the principle problems of using TPM based keys is that there's no easy way of integrating them with standard file based keys. This proposal adds a generic method for handling file based engine keys that can be loaded as PEM files. Integration into the PEM loader requires a BIO based engine API callback which the first patch adds. The second patch checks to see if the key can be loaded by any of the present engines. Note that this requires that any engine which is to be used must be present and initialised via openssl.cnf. I'll also post to this list the patch to openssl_tpm_engine that makes use if this infrastructure so the integration of the whole can be seen. It should also be noted that gnutls has had this functionality since 2012. The patch was done against 1.0.2h for easier testing and you can try it and the openssl_tpm_engine out (if you run openSUSE) here: https://build.opensuse.org/project/show/home:jejb1:Tumbleweed James --- v2: make bio callback explicit vi new method rather than overloading keyid --- James Bottomley (2): engine: add new bio based method for loading engine keys pem: load engine keys crypto/engine/eng_int.h | 1 + crypto/engine/eng_pkey.c | 38 ++ crypto/engine/engine.h | 17 + crypto/pem/pem_pkey.c| 4 4 files changed, 60 insertions(+) -- openssl-dev mailing list To unsubscribe: https://mta.openssl.org/mailman/listinfo/openssl-dev
Re: [openssl-dev] [RFC 0/2] Proposal for seamless handling of TPM based RSA keys in openssl
On Wed, 2016-11-23 at 10:53 +, David Woodhouse wrote: > On Wed, 2016-11-23 at 11:47 +0100, Richard Levitte wrote: > > > > Right... > > > > But then, embedding everything in an OCTET STRING isn't exactly a > > novel idea either. How do we discern a DER encoded TSS KEY BLOB > > from whatever else that had the same "novel" idea? An OCTET STRING > > is an OCTET STRING is an OCTET STRING... See the dragons hovering > > over there? ;-) > > We don't. Crap like that is auto-detected in PEM form only. And yes, > it *really* should have used the TssBlob structure, not just the > OCTET STRING. Well, not that I'm advocating doing this, but for TPM keys we actually can. The binary content is recognisable even if it just contains a TPM_KEY12 structure. The first two bytes are a fixed tag, the second two must be zero and then we have a set of flags and length fields with fairly restricted value ranges. The encrypted private key, authority and hashes are at the end, so there's an effective and quite long header at the beginning. For an RSA2048 key, the structure will always be 559 bytes long as well. However, to get back to the plan: you want an additional "do I recognise this PEM" file callback instead of a "try this bio" one. I can code that up and see what it looks like. James smime.p7s Description: S/MIME cryptographic signature -- openssl-dev mailing list To unsubscribe: https://mta.openssl.org/mailman/listinfo/openssl-dev
Re: [openssl-dev] [RFC 0/2] Proposal for seamless handling of TPM based RSA keys in openssl
On Tue, 2016-11-22 at 18:03 +, Salz, Rich wrote: > > > It does this by trying to interpret the blob against known ASN.1 > > > definitions, and will only succeed when there's a complete match. > > > I'm > > > not terribly worried... > > I am. With locales and UTF8, the old simple days of text/binary are > probably long gone. And if any ASN.1 definition has extensibility in > it, then we have to be concerned about things being wrapped, > something like prefix attacks, and so on. > > > And even if you were, you should be *more* worried about making > > *applications* do it for themselves :) > > I cannot control what an application does, and I am not responsible > for any other application's reputation. I do have a strongly vested > stake in OpenSSL's. > > It is already possible to write a utility library that tries > everything in turn, and returns an enumeration that says "seems to be > an X509 certificate" etc. And then another routine that takes that > enumeration and the blob and calls the right decoder. I would be > okay with that, even if it were part of OpenSSL. I am opposed to > guessing and parsing in one step, and would -1 any PR for that, > forcing a team discussion. That's not the proposal. The proposal is to use PEM form because we can make it uniquely self describing using the guard tags which obviates the problem above. On the larger issue of non-self describing formats like ASN.1: if your theory that there's a security hole by allowing opportunistic format detection is correct, simply making the user specify is palming our bug off on to the user and abdicating responsibility because now when they're tricked into an exploit they can be blamed not openssl. If such a bug exists, doing opportunistic format detection the better guarantor of overall system security because if such a bug is found, it would have to be fixed within openssl to everyone's benefit. James -- openssl-dev mailing list To unsubscribe: https://mta.openssl.org/mailman/listinfo/openssl-dev
Re: [openssl-dev] [RFC 0/2] Proposal for seamless handling of TPM based RSA keys in openssl
On Tue, 2016-11-22 at 16:28 +, David Woodhouse wrote: > On Tue, 2016-11-22 at 17:21 +0100, Richard Levitte wrote: > > > > dwmw2> It is *only* the OCTET STRING of the blob itself. Everything > > else is > > dwmw2> redundant anyway. > > > > Oh! Ok, that makes things much simpler (at least in a way) > > Kind of. But then again, there's an argument that it was none of your > business anyway. If it says "BEGIN TSS KEY BLOB" you hand it off to > the > TPM engine and after that you really don't care about what's in it. > > Once upon a time, the TPM engine wrote those TPM_KEY blobs to binary > files (no ASN.1 at all). For some reason it didn't use the TssBlob > object type, although perhaps it should. > > When I started looking at it, I used the -BEGIN TSS KEY BLOB- > for an OCTET STRING containing *just* that the code had previously > been > writing into its binary files. > > If I'd been aware of the TssBlob definition at that time, I suppose I > would have used it instead of just the OCTET STRING. But I didn't. > > If we write an I-D covering the TPM keys, perhaps the PEM contents > should be permitted to be *either* a raw OCTET STRING with the key > blob, OR a TssBlob object. Or maybe we should add a > BEGIN TSS BLOB- (without 'KEY' in it) instead? Before we rathole on this: if we use the current code to just hand off to the engine, openssl never needs to know the format of the key files or even what they mean. If we hard code recognising TPM keys into openssl, we are going to have to agree (and stick to) a key format. This is one of the decisions that needs making to transform the RFC into a real patch. I will note that gnutls does hard code recognising TPM keys so there's precedent for doing it that way. However, I have a marginal preference for letting the loaded engines do it because that's the way that gives most flexibility with regard to new engines as they come along. This problem isn't theoretical: TPM 2.0 keys are very different from TPM 1.2 ones, so they'll likely have a new engine to handle them and a new file format. James smime.p7s Description: S/MIME cryptographic signature -- openssl-dev mailing list To unsubscribe: https://mta.openssl.org/mailman/listinfo/openssl-dev
Re: [openssl-dev] [RFC 0/2] Proposal for seamless handling of TPM based RSA keys in openssl
On Tue, 2016-11-22 at 16:32 +0100, Richard Levitte wrote: > In message <1479815862.8937.22.ca...@infradead.org> on Tue, 22 Nov > 2016 11:57:42 +, David Woodhouse said: > > dwmw2> Besides, it requires files in the form described by the > Portable Data > dwmw2> section of the TSS (1.2) spec. That's a SEQUENCE with a blob > type > dwmw2> (which is mostly redundant as in this case we're always > talking about > dwmw2> key blobs), the blob length (which is entirely redundant) and > then the > dwmw2> actual blob as an OCTET STRING. I don't know of any tool which > actually > dwmw2> creates such files. > > I'm just having a look at the spec (page 151 in > http://www.trustedcomputinggroup.org/wp-content/uploads/TSS_1_2_Errat > a_A-final.pdf), and am a bit confused by the TssBlobType type. Which > is it in practice, an ENUMERATED or an INTEGER? It's actually here: http://trustedcomputinggroup.org/wp-content/uploads/TPM-Main-Part-2-TPM-Structures_v1.2_rev116_01032011.pdf It's around page 101, section 10.3 the TPM_KEY12 structure. That tells you what to encrypt and how to construct the encrypted part of the blob. It refers to other structures, so you end up doing a bit of a pointer chase through the document. James -- openssl-dev mailing list To unsubscribe: https://mta.openssl.org/mailman/listinfo/openssl-dev
Re: [openssl-dev] [RFC 0/2] Proposal for seamless handling of TPM based RSA keys in openssl
On Mon, 2016-11-21 at 13:42 +, David Woodhouse wrote: > On Wed, 2016-11-16 at 19:07 +0100, Richard Levitte wrote: > > > > Many years ago, I was thinking of something along the same lines, > > but with a .pem file that would just have a few headers, holding > > the name of the intended engine and the key identity, something > > like this: > > > > -BEGIN PRIVATE KEY- > > X-key-id: flarflarflar > > X-key-engine: foo > > -END PRIVATE KEY- > > > > The intent was that the PEM code would be massaged to recognise > > these headers and would then use ENGINE_by_id() / > > ENGINE_load_private_key() with those data and that would be it. > > > > James, did I catch your intention about right? I think that's > > essentially what e_tpm.c does for loading keys, right? Yes, that's right. When any SSL program sees a TPM wrapped key, it should just do the right thing if it has the engine capability without needing the user to add any options to the command line. > Right. The TPM engine currently uses BEGIN TSS KEY BLOB-; I > added that a few years back (it used to just dump the binary blob > instead). Both the TPM ENGINE and GnuTLS will load those files, as > noted at http://www.infradead.org/openconnect/tpm.html > > The problem is that applications have to jump through special hoops > to recognise the files and invoke the engine (and there's a special > API in GnuTLS too). It would be good if the appropriate engine could > be invoked *automatically*, so the crypto library just does the right > thing without all the applications even having to *know* about it. > (Just like GnuTLS will automatically Just Work in many situations > when presented with a PKCS#11 URI instead a filename, as OpenSSL also > should, but doesn't yet.) > > However, the contents of the PEM file should *not* be OpenSSL > -specific and have engine names; I objected to James's original > incarnation of this, which had something like > -BEGIN tpm ENGINE PRIVATE KEY- > and had the "tpm" engine automatically loaded on demand. It needs to > be something generic. Which means engines need to indicate *which* > PEM headers they can grok. And maybe the solution to this will tie in > with the general fixes we need for "normal" key files, so that > applications can Just Work with all of those too (qv¹). Right, I forgot to add in the blurb that I'm looking for a mechanism that all SSL implementations could follow, so it can't be tied to anything specific in openSSL (like the engine name). I modelled it on gnutls because that has the same "just works(tm)" characteristic that I was looking for. > Once the dust settles on TPMv2.0 we should probably put together an I > -D for the TPM-wrapped blob PEM files. And I should definitely add > something about them to ¹. Once we agree, I'll be happy to write up something. We can use the pem header concept to extend this format if it becomes necessary. James smime.p7s Description: S/MIME cryptographic signature -- openssl-dev mailing list To unsubscribe: https://mta.openssl.org/mailman/listinfo/openssl-dev
[openssl-dev] [RFC 2/2] pem: load engine keys
Before trying to process the PEM file, hand it to each of the loaded engines to see if they can load it. This uses the new bio based callback, so the engine must be loaded and implement this callback to be considered. Signed-off-by: James Bottomley --- crypto/pem/pem_pkey.c | 5 + 1 file changed, 5 insertions(+) diff --git a/crypto/pem/pem_pkey.c b/crypto/pem/pem_pkey.c index 04d6319..8d44d45 100644 --- a/crypto/pem/pem_pkey.c +++ b/crypto/pem/pem_pkey.c @@ -85,6 +85,11 @@ EVP_PKEY *PEM_read_bio_PrivateKey(BIO *bp, EVP_PKEY **x, pem_password_cb *cb, int slen; EVP_PKEY *ret = NULL; +if (ENGINE_find_engine_load_key(NULL, &ret, (const char *)bp, cb, u, + ENGINE_LOAD_KEY_FLAG_BIO) == 1) { +return ret; +} + if (!PEM_bytes_read_bio(&data, &len, &nm, PEM_STRING_EVP_PKEY, bp, cb, u)) return NULL; p = data; -- openssl-dev mailing list To unsubscribe: https://mta.openssl.org/mailman/listinfo/openssl-dev
[openssl-dev] [RFC 0/2] Proposal for seamless handling of TPM based RSA keys in openssl
[David Woodhouse told me that openssl-dev is a closed list, so the original messages got trashed. This is a resend with apologies to David and Peter] One of the principle problems of using TPM based keys is that there's no easy way of integrating them with standard file based keys. This proposal adds a generic method for handling file based engine keys that can be loaded as PEM files. Integration into the PEM loader requires a BIO based engine API callback which the first patch adds. The second patch checks to see if the key can be loaded by any of the present engines. Note that this requires that any engine which is to be used must be present and initialised via openssl.cnf. I'll also post to this list the patch to openssl_tpm_engine that makes use if this infrastructure so the integration of the whole can be seen. It should also be noted that gnutls has had this functionality since 2012. The patch was done against 1.0.2h for easier testing and you can try it and the openssl_tpm_engine out (if you run openSUSE) here: https://build.opensuse.org/project/show/home:jejb1:Tumbleweed James --- James Bottomley (2): engine: add new flag based method for loading engine keys pem: load engine keys crypto/engine/eng_int.h | 1 + crypto/engine/eng_pkey.c | 38 ++ crypto/engine/engine.h | 26 ++ crypto/pem/pem_pkey.c| 5 + 4 files changed, 70 insertions(+) -- openssl-dev mailing list To unsubscribe: https://mta.openssl.org/mailman/listinfo/openssl-dev
[openssl-dev] [RFC 1/2] engine: add new flag based method for loading engine keys
The assumption in all the current engine code is that key_id can be passed as something like a file name. There are some new users that actually want to pass a BIO, so add a new load_key method for engines that takes a flag value. The first defined flag is ENGINE_LOAD_KEY_FLAG_BIO which means that the key_id is actually a bio pointer. Signed-off-by: James Bottomley --- crypto/engine/eng_int.h | 1 + crypto/engine/eng_pkey.c | 38 ++ crypto/engine/engine.h | 26 ++ 3 files changed, 65 insertions(+) diff --git a/crypto/engine/eng_int.h b/crypto/engine/eng_int.h index 46f163b..b65cc41 100644 --- a/crypto/engine/eng_int.h +++ b/crypto/engine/eng_int.h @@ -197,6 +197,7 @@ struct engine_st { ENGINE_CTRL_FUNC_PTR ctrl; ENGINE_LOAD_KEY_PTR load_privkey; ENGINE_LOAD_KEY_PTR load_pubkey; +ENGINE_LOAD_KEY_FLAGS_PTR load_key_flags; ENGINE_SSL_CLIENT_CERT_PTR load_ssl_client_cert; const ENGINE_CMD_DEFN *cmd_defns; int flags; diff --git a/crypto/engine/eng_pkey.c b/crypto/engine/eng_pkey.c index 23580d9..124426f 100644 --- a/crypto/engine/eng_pkey.c +++ b/crypto/engine/eng_pkey.c @@ -64,6 +64,13 @@ int ENGINE_set_load_privkey_function(ENGINE *e, return 1; } +int ENGINE_set_load_key_flags_function(ENGINE *e, + ENGINE_LOAD_KEY_FLAGS_PTR load_f) +{ +e->load_key_flags = load_f; +return 1; +} + int ENGINE_set_load_pubkey_function(ENGINE *e, ENGINE_LOAD_KEY_PTR loadpub_f) { e->load_pubkey = loadpub_f; @@ -88,6 +95,11 @@ ENGINE_LOAD_KEY_PTR ENGINE_get_load_pubkey_function(const ENGINE *e) return e->load_pubkey; } +ENGINE_LOAD_KEY_FLAGS_PTR ENGINE_get_load_key_flags_function(const ENGINE *e) +{ +return e->load_key_flags; +} + ENGINE_SSL_CLIENT_CERT_PTR ENGINE_get_ssl_client_cert_function(const ENGINE *e) { @@ -184,3 +196,29 @@ int ENGINE_load_ssl_client_cert(ENGINE *e, SSL *s, return e->load_ssl_client_cert(e, s, ca_dn, pcert, ppkey, pother, ui_method, callback_data); } + +int ENGINE_find_engine_load_key(ENGINE **e, EVP_PKEY **pkey, const char *key_id, +pem_password_cb *cb, void *cb_data, +unsigned int flags) +{ +ENGINE *ep; +int ret = 0; + +for (ep = ENGINE_get_first(); ep != NULL; ep = ENGINE_get_next(ep)) { +if (!ep->load_key_flags) +continue; +if (ep->load_key_flags(ep, pkey, key_id, cb, cb_data, flags) == 1) { +ret = 1; +break; +} + if (flags & ENGINE_LOAD_KEY_FLAG_BIO) +(void)BIO_reset((BIO *)key_id); + ERR_clear_error(); +} +if (e) +*e = ep; +else if (ep) +ENGINE_free(ep); + +return ret; +} diff --git a/crypto/engine/engine.h b/crypto/engine/engine.h index bd7b591..49f6a55 100644 --- a/crypto/engine/engine.h +++ b/crypto/engine/engine.h @@ -97,6 +97,7 @@ # include # include +# include #ifdef __cplusplus extern "C" { @@ -338,6 +339,19 @@ typedef int (*ENGINE_CTRL_FUNC_PTR) (ENGINE *, int, long, void *, typedef EVP_PKEY *(*ENGINE_LOAD_KEY_PTR)(ENGINE *, const char *, UI_METHOD *ui_method, void *callback_data); + +/* + * This flag signals that the const char *key_id (3rd argument) actually + * points to a SSL BIO structure + */ +#define ENGINE_LOAD_KEY_FLAG_BIO 0x01 + +/* Replacement load_key with flags and return code */ +typedef int (*ENGINE_LOAD_KEY_FLAGS_PTR)(ENGINE *, EVP_PKEY **, +const char *, +pem_password_cb *pwd_callback, +void *callback_data, +unsigned int flags); typedef int (*ENGINE_SSL_CLIENT_CERT_PTR) (ENGINE *, SSL *ssl, STACK_OF(X509_NAME) *ca_dn, X509 **pcert, EVP_PKEY **pkey, @@ -565,6 +579,8 @@ int ENGINE_set_finish_function(ENGINE *e, ENGINE_GEN_INT_FUNC_PTR finish_f); int ENGINE_set_ctrl_function(ENGINE *e, ENGINE_CTRL_FUNC_PTR ctrl_f); int ENGINE_set_load_privkey_function(ENGINE *e, ENGINE_LOAD_KEY_PTR loadpriv_f); +int ENGINE_set_load_key_flags_function(ENGINE *e, + ENGINE_LOAD_KEY_FLAGS_PTR loadpriv_f); int ENGINE_set_load_pubkey_function(ENGINE *e, ENGINE_LOAD_KEY_PTR loadpub_f); int ENGINE_set_load_ssl_client_cert_function(ENGINE *e, ENGINE_SSL_CLIENT_CERT_PTR @@ -611,6 +627,7 @@ ENGINE_GEN_INT_FUNC_PTR ENGINE_get_finish_function(const ENGINE *e); ENGINE_CTRL_FUNC_PTR ENGINE_get_ctrl_function(con
[openssl-dev] [PATCH] openssl tpm engine: add new openssl bio method for seamless loading of tpm keys
Permits this engine to be used as part of the openssl pem routines for loading TPM based keys. To use this, the tpm engine must be preloaded via the openssl.cnf file Signed-off-by: James Bottomley diff --git a/e_tpm.c b/e_tpm.c index 3e20f8e..9cb1d6c 100644 --- a/e_tpm.c +++ b/e_tpm.c @@ -43,13 +43,19 @@ #ifndef OPENSSL_NO_HW #ifndef OPENSSL_NO_HW_TPM +struct tpm_ui { +UI_METHOD *ui_method; +pem_password_cb *pem_cb; +}; + /* engine specific functions */ static int tpm_engine_destroy(ENGINE *); static int tpm_engine_init(ENGINE *); static int tpm_engine_finish(ENGINE *); static int tpm_engine_ctrl(ENGINE *, int, long, void *, void (*)()); static EVP_PKEY *tpm_engine_load_key(ENGINE *, const char *, UI_METHOD *, void *); -static char *tpm_engine_get_auth(UI_METHOD *, char *, int, char *, void *); +static int tpm_engine_load_key_flags(ENGINE *, EVP_PKEY **, const char *, pem_password_cb *, void *, unsigned int); +static char *tpm_engine_get_auth(struct tpm_ui *, char *, int, char *, void *); #ifndef OPENSSL_NO_RSA /* rsa functions */ @@ -212,6 +218,9 @@ static int bind_helper(ENGINE * e) !ENGINE_set_ctrl_function(e, tpm_engine_ctrl) || !ENGINE_set_load_pubkey_function(e, tpm_engine_load_key) || !ENGINE_set_load_privkey_function(e, tpm_engine_load_key) || +#ifdef ENGINE_LOAD_KEY_FLAG_BIO +!ENGINE_set_load_key_flags_function(e, tpm_engine_load_key_flags) || +#endif !ENGINE_set_cmd_defns(e, tpm_cmd_defns)) return 0; @@ -244,7 +253,7 @@ void ENGINE_load_tpm(void) ERR_clear_error(); } -int tpm_load_srk(UI_METHOD *ui, void *cb_data) +int tpm_load_srk(struct tpm_ui *ui, void *cb_data) { TSS_RESULT result; UINT32 authusage; @@ -451,8 +460,9 @@ err: return 0; } -static char *tpm_engine_get_auth(UI_METHOD *ui_method, char *auth, int maxlen, -char *input_string, void *cb_data) +static char *tpm_engine_get_auth_ui(UI_METHOD *ui_method, char *auth, + int maxlen, char *input_string, + void *cb_data) { UI *ui; @@ -479,6 +489,30 @@ static char *tpm_engine_get_auth(UI_METHOD *ui_method, char *auth, int maxlen, return auth; } +static char *tpm_engine_get_auth_pem(pem_password_cb *pem_cb, char *auth, + int maxlen, char *input_string, + void *cb_data) +{ + EVP_set_pw_prompt(input_string); + if (!pem_cb) + pem_cb = PEM_def_callback; + pem_cb(auth, maxlen, 0, cb_data); + EVP_set_pw_prompt(NULL); + + return auth; +} + +static char *tpm_engine_get_auth(struct tpm_ui *ui, char *auth, + int maxlen, char *input_string, void *cb_data) +{ + if (ui->ui_method) + return tpm_engine_get_auth_ui(ui->ui_method, auth, maxlen, + input_string, cb_data); + else + return tpm_engine_get_auth_pem(ui->pem_cb, auth, maxlen, + input_string, cb_data); +} + static int tpm_engine_finish(ENGINE * e) { DBG("%s", __FUNCTION__); @@ -575,8 +609,19 @@ int fill_out_rsa_object(RSA *rsa, TSS_HKEY hKey) return 1; } -static EVP_PKEY *tpm_engine_load_key(ENGINE *e, const char *key_id, -UI_METHOD *ui, void *cb_data) +static inline int tpm_flag_is_bio(unsigned int flags) +{ +#ifdef ENGINE_LOAD_KEY_FLAG_BIO + return flags & ENGINE_LOAD_KEY_FLAG_BIO; +#else + return 0; +#endif +} + +static int tpm_engine_load_key_core(ENGINE *e, EVP_PKEY **ppkey, + const char *key_id, + struct tpm_ui *ui, + void *cb_data, unsigned int flags) { ASN1_OCTET_STRING *blobstr; TSS_HKEY hKey; @@ -591,37 +636,55 @@ static EVP_PKEY *tpm_engine_load_key(ENGINE *e, const char *key_id, if (!key_id) { TSSerr(TPM_F_TPM_ENGINE_LOAD_KEY, ERR_R_PASSED_NULL_PARAMETER); - return NULL; - } - - if (!tpm_load_srk(ui, cb_data)) { - TSSerr(TPM_F_TPM_ENGINE_LOAD_KEY, TPM_R_SRK_LOAD_FAILED); - return NULL; + return 0; } - if ((bf = BIO_new_file(key_id, "r")) == NULL) { - TSSerr(TPM_F_TPM_ENGINE_LOAD_KEY, - TPM_R_FILE_NOT_FOUND); - return NULL; + if (tpm_flag_is_bio(flags)) { + bf = (BIO *)key_id; + } else { + if ((bf = BIO_new_file(key_id, "r")) == NULL) { + TSSerr(TPM_F_TPM_ENGINE_LOAD_KEY, + TPM_R_FILE_NOT_FOUND); + return 0; + } }