You are viewing a plain text version of this content. The canonical link for it is here.
Posted to dev@tomcat.apache.org by Christopher Schultz <ch...@christopherschultz.net> on 2021/08/25 14:10:17 UTC

OT: Parsing EC private keys in PEM format

All,

I'm trying to do this without looking at the code which is in Tomcat 
because I'd like to release it separately and not have to worry about 
figuring out hos to get permission, etc.

I'm working on a piece of code which can load the following types of 
PEM-encoded DER files with private keys in them. Each is a different 
flavor of terrible.

BEGIN PRIVATE KEY (pkcs8, pretty easy)
BEGIN RSA PRIVATE KEY (RFC 3447/pkcs1, requires ASN.1)
BEGIN RSA PRIVATE KEY (with encryption)
BEGIN EC PRIVATE KEY (RFC 5915, requires ASN.1)
BEGIN ENCRYPTED PRIVATE KEY (also pkcs8)

I have completed the work on these:

BEGIN PRIVATE KEY
BEGIN RSA PRIVATE KEY
BEGIN RSA PRIVATE KEY (with encryption)

I'm now working on:

BEGIN EC PRIVATE KEY

I think I can get everything I need out of the ASN.1 structure of the 
file, but I'm getting caught up in the Java API for EC crypto.

In order to create an RSA private key, one need only assemble the 
various values required for the RSA key (e, n, etc.) and stick them into 
an RSAPrivateKeySpec object, then generate the key from the KeySpec.

For EC, however, you need what appears to be a whole menagerie of 
classes, many of which it's not clear how to construct.

Is there an easier way to do this? Shortcuts are fine: I'm not married 
to the idea of manually-parsing the ASN.1 structure and 
manually-building the Java objects required if the API already supports 
some sort of shortcut.

If there is *not* an easier way to do this, I'm wondering how to 
construct the following objects. Here is the code I have so far:

String algorithm = "EC"; // I know this from the file type
byte[] keybytes = ...; // These come from the ASN.1 structure
String curveOID = ...; // This comes from the ASN.1 stucture
byte[] paramBits = ...; // This also comes from the ASN.1 structure

Curve curve = getCurve(curveOID); // I have this, at least for the one 
curve I'm working with at the moment

ECField ecField = ???; // This should be a part of the curve definition?

EllipticCurve curve = new EllipticCurve(ecField, curve.getA(), 
curve.getB());

ECParameterSpec paramSpec = ???; // How to convert paramBits to this?

// This is the easy part
PrivateKey key = KeyFactory.getInstance(algorithm).generatePrivate(new 
ECPrivateKeySpec(new BigInteger(keybytes), paramSpec));

Is there a better way to get the curve definition (from e.g. the OID) 
than manually-building the ECField and EllipticCurve objects?

Thanks,
-chris


---------------------------------------------------------------------
To unsubscribe, e-mail: dev-unsubscribe@tomcat.apache.org
For additional commands, e-mail: dev-help@tomcat.apache.org


Re: OT: Parsing EC private keys in PEM format

Posted by Christopher Schultz <ch...@christopherschultz.net>.
Mark,

On 8/26/21 06:08, Mark Thomas wrote:
> On 25/08/2021 18:04, Christopher Schultz wrote:
>> Mark,
>>
>> On 8/25/21 10:28, Mark Thomas wrote:
>>> On 25/08/2021 15:10, Christopher Schultz wrote:
>>>> All,
>>>>
>>>> I'm trying to do this without looking at the code which is in Tomcat 
>>>> because I'd like to release it separately and not have to worry 
>>>> about figuring out hos to get permission, etc.
>>>
>>> It is ALv2 so the requirements are pretty minimal. You just need to 
>>> include a copy of the ALv2, note you based it on Apache Tomcat and 
>>> don;t use any ASF trademarks in your product name.
>>
>> Hmm. I seem to recall asking someone if I could contribute your 
>> PEMFile stuff to the PostgreSQL JDBC driver project (they only support 
>> non-encrypted DER files directly) and the reply I got was something 
>> along the lines of "horrific copyright violation/IP theft/good luck 
>> finding all the original authors and getting their permission/etc." 
>> (paraphrasing).
> 
> Hmm. Odd. I wonder why they said that. Do you have a public reference to 
> that conversation. Obviously, any potential IP issues are a concern.

I'll look for it.

> Looking at the code, I'm struggling to see where the concern would come 
> from.
> 
> The original contribution was from Emmanuel. Given his work on JSign I 
> have no reason to think the contribution wasn't original.
> 
> The ASN.1 parser was written from scratch by me. There are comment 
> references to various specifications but whatever copyright/license they 
> are under has no bearing on the copyright/licensing of the 
> implementation. (And most, if not all, are RFCs.)

One of the first things I did was write my own ASN.1 parser. It looks 
like you went for the barest of bones, while I went a step or so farther.

> The other commits are essentially cosmetic / refactoring.
> 
> If they wanted to relicense the code rather than use it under the ALv2 
> then I can see how they might view that as potentially difficult 
> although in this instance given all the people involved are Tomcat 
> committers it would likely be fairly simple (assuming all the 
> contributors were happy).

PostgreSQL has their own license[1]. It's pretty bare-bones, in the MIT 
style.

I found a PRIVATE KEY[2] that my code cannot open without some 
additional work. I'm going to try it with Tomcat to see if we have the 
same issue.

There is code and references in one of the SO answers that enabled me to 
adapt my code to with with that type of encrypted key.

Thanks,
-chris

[1] https://www.postgresql.org/about/licence/
[2] 
https://stackoverflow.com/questions/63832456/parsing-encrypted-pkcs8-encoded-pem-file-programatically

---------------------------------------------------------------------
To unsubscribe, e-mail: dev-unsubscribe@tomcat.apache.org
For additional commands, e-mail: dev-help@tomcat.apache.org


Re: OT: Parsing EC private keys in PEM format

Posted by Emmanuel Bourg <eb...@apache.org>.
Le 26/08/2021 à 12:08, Mark Thomas a écrit :

> Hmm. Odd. I wonder why they said that. Do you have a public reference to
> that conversation. Obviously, any potential IP issues are a concern.
> 
> Looking at the code, I'm struggling to see where the concern would come
> from.
> 
> The original contribution was from Emmanuel. Given his work on JSign I
> have no reason to think the contribution wasn't original.

Note that Jsign doesn't share the PEM parsing code I contributed to
Tomcat, it uses the PEMParser class [1] from BouncyCastle which handles
more formats (in a very different way).

BouncyCastle being released under the MIT license, maybe their parser
could better fit the PostgreSQL needs?

Emmanuel Bourg

[1]
https://github.com/bcgit/bc-java/blob/master/pkix/src/main/java/org/bouncycastle/openssl/PEMParser.java

---------------------------------------------------------------------
To unsubscribe, e-mail: dev-unsubscribe@tomcat.apache.org
For additional commands, e-mail: dev-help@tomcat.apache.org


Re: OT: Parsing EC private keys in PEM format

Posted by Mark Thomas <ma...@apache.org>.
On 25/08/2021 18:04, Christopher Schultz wrote:
> Mark,
> 
> On 8/25/21 10:28, Mark Thomas wrote:
>> On 25/08/2021 15:10, Christopher Schultz wrote:
>>> All,
>>>
>>> I'm trying to do this without looking at the code which is in Tomcat 
>>> because I'd like to release it separately and not have to worry about 
>>> figuring out hos to get permission, etc.
>>
>> It is ALv2 so the requirements are pretty minimal. You just need to 
>> include a copy of the ALv2, note you based it on Apache Tomcat and 
>> don;t use any ASF trademarks in your product name.
> 
> Hmm. I seem to recall asking someone if I could contribute your PEMFile 
> stuff to the PostgreSQL JDBC driver project (they only support 
> non-encrypted DER files directly) and the reply I got was something 
> along the lines of "horrific copyright violation/IP theft/good luck 
> finding all the original authors and getting their permission/etc." 
> (paraphrasing).

Hmm. Odd. I wonder why they said that. Do you have a public reference to 
that conversation. Obviously, any potential IP issues are a concern.

Looking at the code, I'm struggling to see where the concern would come 
from.

The original contribution was from Emmanuel. Given his work on JSign I 
have no reason to think the contribution wasn't original.

The ASN.1 parser was written from scratch by me. There are comment 
references to various specifications but whatever copyright/license they 
are under has no bearing on the copyright/licensing of the 
implementation. (And most, if not all, are RFCs.)

The other commits are essentially cosmetic / refactoring.

If they wanted to relicense the code rather than use it under the ALv2 
then I can see how they might view that as potentially difficult 
although in this instance given all the people involved are Tomcat 
committers it would likely be fairly simple (assuming all the 
contributors were happy).

Mark

---------------------------------------------------------------------
To unsubscribe, e-mail: dev-unsubscribe@tomcat.apache.org
For additional commands, e-mail: dev-help@tomcat.apache.org


Re: OT: Parsing EC private keys in PEM format

Posted by Christopher Schultz <ch...@christopherschultz.net>.
Mark,

On 8/25/21 10:28, Mark Thomas wrote:
> On 25/08/2021 15:10, Christopher Schultz wrote:
>> All,
>>
>> I'm trying to do this without looking at the code which is in Tomcat 
>> because I'd like to release it separately and not have to worry about 
>> figuring out hos to get permission, etc.
> 
> It is ALv2 so the requirements are pretty minimal. You just need to 
> include a copy of the ALv2, note you based it on Apache Tomcat and don;t 
> use any ASF trademarks in your product name.

Hmm. I seem to recall asking someone if I could contribute your PEMFile 
stuff to the PostgreSQL JDBC driver project (they only support 
non-encrypted DER files directly) and the reply I got was something 
along the lines of "horrific copyright violation/IP theft/good luck 
finding all the original authors and getting their permission/etc." 
(paraphrasing).

>> I'm working on a piece of code which can load the following types of 
>> PEM-encoded DER files with private keys in them. Each is a different 
>> flavor of terrible.
>>
>> BEGIN PRIVATE KEY (pkcs8, pretty easy)
>> BEGIN RSA PRIVATE KEY (RFC 3447/pkcs1, requires ASN.1)
>> BEGIN RSA PRIVATE KEY (with encryption)
>> BEGIN EC PRIVATE KEY (RFC 5915, requires ASN.1)
>> BEGIN ENCRYPTED PRIVATE KEY (also pkcs8)
>>
>> I have completed the work on these:
>>
>> BEGIN PRIVATE KEY
>> BEGIN RSA PRIVATE KEY
>> BEGIN RSA PRIVATE KEY (with encryption)
>>
>> I'm now working on:
>>
>> BEGIN EC PRIVATE KEY
>>
>> I think I can get everything I need out of the ASN.1 structure of the 
>> file, but I'm getting caught up in the Java API for EC crypto.
>>
>> In order to create an RSA private key, one need only assemble the 
>> various values required for the RSA key (e, n, etc.) and stick them 
>> into an RSAPrivateKeySpec object, then generate the key from the KeySpec.
>>
>> For EC, however, you need what appears to be a whole menagerie of 
>> classes, many of which it's not clear how to construct.
>>
>> Is there an easier way to do this? Shortcuts are fine: I'm not married 
>> to the idea of manually-parsing the ASN.1 structure and 
>> manually-building the Java objects required if the API already 
>> supports some sort of shortcut.
>>
>> If there is *not* an easier way to do this, I'm wondering how to 
>> construct the following objects. Here is the code I have so far:
>>
>> String algorithm = "EC"; // I know this from the file type
>> byte[] keybytes = ...; // These come from the ASN.1 structure
>> String curveOID = ...; // This comes from the ASN.1 stucture
>> byte[] paramBits = ...; // This also comes from the ASN.1 structure
>>
>> Curve curve = getCurve(curveOID); // I have this, at least for the one 
>> curve I'm working with at the moment
>>
>> ECField ecField = ???; // This should be a part of the curve definition?
>>
>> EllipticCurve curve = new EllipticCurve(ecField, curve.getA(), 
>> curve.getB());
>>
>> ECParameterSpec paramSpec = ???; // How to convert paramBits to this?
>>
>> // This is the easy part
>> PrivateKey key = KeyFactory.getInstance(algorithm).generatePrivate(new 
>> ECPrivateKeySpec(new BigInteger(keybytes), paramSpec));
>>
>> Is there a better way to get the curve definition (from e.g. the OID) 
>> than manually-building the ECField and EllipticCurve objects?
> 
> Sorry, I'd have to look at the Tomcat code to answer that. That isn't 
> really any different to you looking yourself.

Interesting. You parse the ASN.1 structure and re-write it into PKCS#8 
ASN, then parse it as such.

It occurs to me that, like Digester and possibly other components before 
it, Tomcat has some useful cryptographic functions that we might 
consider packaging separately. I think a component which can read a 
PEMFile in its many incarnations is a very valuable thing on its own.

-chris

---------------------------------------------------------------------
To unsubscribe, e-mail: dev-unsubscribe@tomcat.apache.org
For additional commands, e-mail: dev-help@tomcat.apache.org


Re: OT: Parsing EC private keys in PEM format

Posted by Mark Thomas <ma...@apache.org>.
On 25/08/2021 15:10, Christopher Schultz wrote:
> All,
> 
> I'm trying to do this without looking at the code which is in Tomcat 
> because I'd like to release it separately and not have to worry about 
> figuring out hos to get permission, etc.

It is ALv2 so the requirements are pretty minimal. You just need to 
include a copy of the ALv2, note you based it on Apache Tomcat and don;t 
use any ASF trademarks in your product name.

> I'm working on a piece of code which can load the following types of 
> PEM-encoded DER files with private keys in them. Each is a different 
> flavor of terrible.
> 
> BEGIN PRIVATE KEY (pkcs8, pretty easy)
> BEGIN RSA PRIVATE KEY (RFC 3447/pkcs1, requires ASN.1)
> BEGIN RSA PRIVATE KEY (with encryption)
> BEGIN EC PRIVATE KEY (RFC 5915, requires ASN.1)
> BEGIN ENCRYPTED PRIVATE KEY (also pkcs8)
> 
> I have completed the work on these:
> 
> BEGIN PRIVATE KEY
> BEGIN RSA PRIVATE KEY
> BEGIN RSA PRIVATE KEY (with encryption)
> 
> I'm now working on:
> 
> BEGIN EC PRIVATE KEY
> 
> I think I can get everything I need out of the ASN.1 structure of the 
> file, but I'm getting caught up in the Java API for EC crypto.
> 
> In order to create an RSA private key, one need only assemble the 
> various values required for the RSA key (e, n, etc.) and stick them into 
> an RSAPrivateKeySpec object, then generate the key from the KeySpec.
> 
> For EC, however, you need what appears to be a whole menagerie of 
> classes, many of which it's not clear how to construct.
> 
> Is there an easier way to do this? Shortcuts are fine: I'm not married 
> to the idea of manually-parsing the ASN.1 structure and 
> manually-building the Java objects required if the API already supports 
> some sort of shortcut.
> 
> If there is *not* an easier way to do this, I'm wondering how to 
> construct the following objects. Here is the code I have so far:
> 
> String algorithm = "EC"; // I know this from the file type
> byte[] keybytes = ...; // These come from the ASN.1 structure
> String curveOID = ...; // This comes from the ASN.1 stucture
> byte[] paramBits = ...; // This also comes from the ASN.1 structure
> 
> Curve curve = getCurve(curveOID); // I have this, at least for the one 
> curve I'm working with at the moment
> 
> ECField ecField = ???; // This should be a part of the curve definition?
> 
> EllipticCurve curve = new EllipticCurve(ecField, curve.getA(), 
> curve.getB());
> 
> ECParameterSpec paramSpec = ???; // How to convert paramBits to this?
> 
> // This is the easy part
> PrivateKey key = KeyFactory.getInstance(algorithm).generatePrivate(new 
> ECPrivateKeySpec(new BigInteger(keybytes), paramSpec));
> 
> Is there a better way to get the curve definition (from e.g. the OID) 
> than manually-building the ECField and EllipticCurve objects?

Sorry, I'd have to look at the Tomcat code to answer that. That isn't 
really any different to you looking yourself.

Mark

---------------------------------------------------------------------
To unsubscribe, e-mail: dev-unsubscribe@tomcat.apache.org
For additional commands, e-mail: dev-help@tomcat.apache.org