Showing posts with label EJBCA. Show all posts
Showing posts with label EJBCA. Show all posts

Thursday, October 1, 2020

Supporting EdDSA - The Details

About EdDSA

EdDSA is a fairly new signature algorithm, at least if we compare to the classic algorithms we use, where RSA was introduced in 1977 and ECDSA entering wide use in the early 2000's. In contrast EdDSA was published in 2011. EdDSA is meant to be simple, elegant, and well defined, so it is hard to make security catastrophic mistakes upon use, something that is rather easy to do with the classic algorithms. EdDSA, with regards to digital signatures, consist of two distinct variants, Ed25519 and Ed448, with different key lengths. The usage of EdDSA, as relevant for us, has been standardized in RFC8032, RFC8410 and RFC8419.

EdDSA in EJBCA

Albeit not very widely used, we have been asked on occasions for support of EdDSA in EJBCA, commonly in IoT related use cases. Due to these requests we added software support for Ed25519 and Ed448 in EJBCA 7.4.0 in June 2020. As EJBCA is used in high security PKIs, Hardware Security Modules are typically used, and we have recently tested support for EdDSA in HSMs. 

This post describes the details of what is involved in supporting this new signature algorithm, in software and in hardware. The final result can be seen in the EJBCA documentation.

A note of caution: implementing cryptography is not for everyone, and we could not have done it without the help of our friends from Bouncy Castle, who helped us with the hard core details, and even gave us an introductory training session on the specific topic of EdDSA. Bouncy Castle support contracts are available though Crypto Workshop.

Software Support

The first step when supporting a new algorithm for PKI usage, in Java, is to get all the ASN.1 and Java crypto stuff in place. Without that, there is no going forward. This includes at least, but not exclusively the following parts:

  • ASN.1 Object identifiers
  • Public and Private key classes
  • Reading and writing (encoding and decoding) said public and private keys
  • SubjectPublicKeyInfo ASN.1 structures for properly encoding public keys in certificates and CSRs
  • Signatures themselves, on at least certificates, CRLs, CSRs, OCSP responses and CMS messages
  • Conversion between names (for example Ed25519) and OIDs (1.3.101.112)

A specific trick worth mentioning, that we stumbled upon, is that there are two versions of encoding/decoding format of EdDSA. A version 1 and a version 2, where different software implementation, for example OpenSSL, produces the v1 format, while others produce the (newer) v2 format. Needless to say, we needed to handle both.

For EJBCA, we are lucky to use the Bouncy Castle crypto APIs, which are commonly among the first to implement anything new. As Bouncy Castle had support for all the relevant RFCs EJBCA could start adding the application layer support right away. There were a few additions needed on the way, mostly related to various corner cases or handling encoding/decoding of keys and PKCS#12 files from different sources, that needed minor additional features in Bouncy Castle. As always, they were fast to add the needed tricks in the crypto API.

Usability

Apart from the core crypto pieces, EJBCA also implement a bunch of usability features making it easy(!) for users to use PKI with various algorithms. With EdDSA being so simple, both the keys and signature algorithm is referred to Ed25519 and Ed448, it still needed some extra code to fit into the overall structure. For the classic algorithms there are countless combinations, for example an RSA 2048 bit key can be used with all RSA signature algorithms:

  • SHA256WithRSA
  • SHA384WithRSA
  • SHA512WithRSA
  • SHA256WithRSAandMGF1
  • ...

Just to name a few. And the same goes for ECDSA, but with even more combinations are there are numerous different EC curves to choose from. All in all there are hundreds of combinations that can be used in EJBCA, and we try to make it easier by or example limiting the available signature algorithms based on the selected key type. So albeit EdDSA having limited number of combinations, some if's and but's in the code is still needed for it to fit in the overall usability framework.


Another trick we play is that a suitable key encryption algorithm is selected, for Key Recovery, based on the signature algorithm used, typically this means selecting an RSA based algorithm, and we have a method for this, where EdDSA had to be added as well.

Adding HSM Support

We, and most of the world, use HSMs through the standard PKCS#11 API. In the until recently latest version of PKCS#11, version 2.40, there was no standardized support for EdDSA. As there was still a requirement from some users for EdDSA, the inevitable result was that some HSM vendors supported EdDSA using what is called Vendor Defined Mechanisms. This is of course a nightmare for product implementors, as specific support has be be built for HSMs from different vendors. PKCS#11 version 3 however, which was released only this year, introduced standardized support for EdDSA.

Now HSM vendors have moved to use the standardized way of supporting EdDSA, which means it's a good time for us to look at supporting HSMs for this algorithm.

Having recently introduced the P11-NG Crypto Token in EJBCA Enterprise, we have low level control of PKCS#11, as used by EJBCA, which was needed in order to support this new feature, P11v3 feature in a P11v2.40 library. In addition, SoftHSMv2 has support for EdDSA, making it easy to develop without access to a real hardware security module.

The last trickery showed up when generating keys and reading them from the HSM. According to the PKCS#11v3 specification the EdDSA public key is generated using the mechanism CKM_EC_EDWARDS_KEY_PAIR_GEN with the same parameters as a normal ECDSA key, which means that a CKA_EC_PARAMS is used in the public key template, with the OID of the curve as parameter, in this case the OID of Ed25519. The public key is then stored as a CKA_EC_POINT. The CKA_EC_POINT is normally used to store EC curve points, but in the case of Ed the point it's not quite the same. This required an if statement and some special handling in the case of EdDSA keys.

In the case of ECDSA:

final java.security.spec.EllipticCurve ellipticCurve = EC5Util.convertCurve(bcspec.getCurve(), bcspec.getSeed());
final java.security.spec.ECPoint ecPoint = ECPointUtil.decodePoint(ellipticCurve,
        ASN1OctetString.getInstance(ckaQ.getValue()).getOctets());
final org.bouncycastle.math.ec.ECPoint ecp = EC5Util.convertPoint(bcspec.getCurve(), ecPoint);
final ECPublicKeySpec pubKeySpec = new ECPublicKeySpec(ecp, bcspec);
final KeyFactory keyfact = KeyFactory.getInstance("ECDSA", BouncyCastleProvider.PROVIDER_NAME);
return keyfact.generatePublic(pubKeySpec);

 and in the case of EdDSA:

X509EncodedKeySpec edSpec = createEdDSAPublicKeySpec(ckaQ.getValue());
final KeyFactory keyfact = KeyFactory.getInstance(oid.getId(), BouncyCastleProvider.PROVIDER_NAME);
return keyfact.generatePublic(edSpec);

As usual, a big thanks to the team at Bouncy Castle for help.

Summary

With all the above details in place, we now have the functionality we need in EJBCA:

  • Generating Ed25519 and Ed448 key pairs (in software and in HSMs)
  • Retrieve public keys
  • Test a key pair
  • Sign and verify
    • Certificate
    • CRL
    • OCSP response
    • CSRs (PKCS#10 and CRMF)
    • CMS message
  • Read and write
    • PEM files
    • PKCS#12 files
  • Presenting EdDSA in Web UIs in a user friendly way 


Cheers,
Tomas Gustavsson
CTO 

EJBCA Enterprise PKI and EJBCA Appliance developed by PrimeKey.

PrimeKey® and EJBCA® are trademarks of PrimeKey Solutions AB, in the EU, the United States, Japan and certain other countries.

Tuesday, February 13, 2018

Roadmap Update: EJBCA 7 and What Lies in Store

Getting roadmap information out of me is usually about as rewarding as mining obscure crypto currencies, but for once I feel that this is a very good opportunity to talk a bit about the roadmap in the next half year, about EJBCA 7 and what is to come.

Technology Leap

Now, the easy announcement is that EJBCA 7 will be released before the end of Q2 of 2018, and the most marked technology leap will be dropping support för JDK7 and JEE6, so those of you who haven't migrated to JDK8 or greater yet should start planning to do so very soon. Things to have in mind:

  • JDK7 had its final support release over a year ago, which is one reason we've chosen to move on.
  • This means that your application server will have to be JBoss EAP 6.3.3 or later.
  • From EJBCA 7 and beyond we'll being using JDK8 features in the source, meaning that you will have to upgrade your JDK/AS before then. In any case we very much recommend upgrading to the latest version of EJBCA as well if you haven't done so yet.

User Interface Changes 

The primary changes you'll be seeing is that we're going to start optimizing and improving workflow in the existing UI. For that reason we'll be removing a lot of pages which have turned redundant or which are too antiquated to maintain.

Public Web


This is going to be the biggest change for many of you, and one of the most dramatic ones: the Public Web is going to be considered deprecated. The reasons for doing so are many, but foremost the fact that the new RA Web does (or nearly, but will do) everything the Public Web does, but better. While I hope that most of you have had a chance to explore and hopefully even start using the RA Web, this is a very good time to start migrating your workflows. If this leaves you with any sense of dread, fret not: we have documented how workflows translate between the Public Web and the RA Web here and here

Note that we won't be removing the Public Web initially but simply not link to, refer to or update it anymore, so there will be an overlap period. 

Admin Web/CA Web

The first major change is a simple one: a question of branding. We have traditionally, both in code and in UI misused the terms Administrator and Administration. In the line of defining an administrator as somebody who performs administrative tasks (which doesn't cover all users of the UI) we'll be renaming the current Admin Web as the CA Web to reflect the fact that its purpose mainly covers setting up CAs and profiles, while the RA Web covers all aspects of of end entity creation and lifecycle management. 

The introduction of the RA Web may have raised some questions about the overlap between the two interfaces, such as the ability to create end entities in both. Naturally, our end goal is to eliminate these overlaps in order to make workflow feel natural an intuitive. For that reason, we'll be deprecating some pages in the CA Web by removing links and references, though as with the Public Web we'll let the pages exist for some time to allow for some overlap. The pages in the CA Web that are going to disappear are (sorted by category):

  • RA Functions
    • Add End Entity
    • Search End Entities
  • Supervision Functions
    • Approve Actions
All of these pages have superior analogues on the RA Web, and it's our goal that our workflows become so intuitive that there will be no need to switch between the two. 

What Comes Next? 

In addition to this, I'd like to let you know a bit about workflows in the UI. Currently the workflows are what could generously be called unintuitive, which is something we're looking to remedy come 2018 and beyond. The design currently largely mirrors the architecture, which while straight forward from a developer's perspective requires way too much domain knowledge from a user's point of view. Our ambition is to start refining and redefining workflows during the coming year to make more sense from what one is trying to accomplish, but we'll be doing so gently and properly documenting and motivating all changes.

We hope you're looking forward to these changes as much as we are!

Cheers!
Mike Agrenius Kushner
Product Owner EJBCA