Hi,

I understand that with the CMP implementation we've submitted a huge chunk of 
code and it is probably not trivial to do the needed checks to ensure the 
OpenSSL project's quality requirements for integrating it.  

I'm a little concerned that this request might eventually be forgotten as the 
request ticket hasn't been seen any update in the RT for ~9 weeks after we have 
submitted the latest code update to enable also using the lightweight HTTP 
implementation for transfer (as more or less suggested).

For planning our further work on that it'd be very helpful if somebody could 
help me understanding where this request for integration might go.

Is there any chance for getting an "owner" for that assigned in RT?  ;-)

Kind regards,
Martin




-----Original Message-----
From: ext Viljanen, Miikka J. via RT [mailto:[email protected]] 
Sent: Thursday, August 15, 2013 3:39 PM
To: Peylo, Martin (NSN - FI/Espoo)
Cc: [email protected]
Subject: Re: [openssl.org #3101] [PATCH] Add CMP (RFC 4210) implementation

Hi,

I just noticed that I had sent this reply only to the openssl-dev list
and not to the request tracker, so I'm sending it again here. I also
slightly updated the patch file and generated it against the latest
OpenSSL snapshot.



On  5.Aug.13 15:09:26, Viljanen, Miikka J. via RT wrote:
> On  2.Aug.13 14:22, Stephen Henson wrote:
> > On Fri Aug 02 10:23:05 2013, [email protected] wrote:
> > >
> > > - the code in crypto/cmp also includes the functionality to perform the
> > > most important cmp message sequences via HTTP. This code depends on
> > > libcurl, so it is split into its own library (libcrypto_cmpseq.a) in
> > > order to help deal with the circular dependency when curl is also
> > > linked with openssl.
> > >
> > 
> > There is some minimal HTTP code which the OpenSSL OCSP library uses and some
> > functions to download certificates and CRLs. Could you use that and avoid 
> > the
> > curl dependency?
>
> 
> The minimal HTTP implementation in OCSP might also be sufficient for what's
> required by CMP. We will look into using that instead of libcurl, and get back
> to you.
> 

We have now adapted the HTTP code from OCSP and use that by default. In case it
is needed to have a full-featured HTTP implementation we have left using curl as
an option during build (`config curl`).  Which one of the HTTP implementations
is used is hidden from applications behind the API.

In case libcurl is used there is now no separate library created anymore.  It is
expected that the users explicitly deciding that curl is to be used resolves the
circular dependency manually on their own.

Now we basically just copied the HTTP code from OCSP, adding the option to use a
proxy on top.  In the future it might make sense to refactor the HTTP code from
OCSP and CMP into its own HTTP client part and use the same in both clients.

The “new” HTTP implementations were successfully tested with the publicly
accessible Insta Certifier and EJBCA implementations.  Text included below is
the updated text of the mail we had sent directly to the opensl-dev mailing list
for details how to build/test.

best regards,
Miikka and Martin



########################## UPDATED FULL PATCH DESCRIPTION #####################

We have developed a patch for OpenSSL adding the client side functionality of
the Certificate Management Protocol (CMP), as defined in RFCs 4210 and 4211.
The code was developed over the last six+ years and is now mature enough that
we'd like to offer it for inclusion in OpenSSL.  We submit the patch with the
CMP code attached to this email also to [email protected] as advised
in the README file.  We will follow comments and participate in discussions
related to the patch on this mailing list.

At the moment, CMP is used mainly for 3GPP specified mobile networks but as
more implementations become available we expect to see more use of the
protocol.  The relevant 3GPP Technical Specification 33.310 profiling CMP usage
is freely available at <http://www.3gpp.org/ftp/Specs/html-info/33310.htm>.

The code has been publicly available through SourceForge so far and we have
received reports that it is also used successfully by other major players in the
telco industry.  The API has remained stable for a while now and we don't see
the need for drastic changes in the future.  We are going to continue supporting
the CMP code after it has been inserted into OpenSSL at least by supplying
needed bugfixes, potentially also by adding more functionality.  Others have
been able do meaningful changes to our code in the past, so we are confident
that it is understandable and well commented.

There are several CMP enabled CA implementations reported to be interoperable
with our client implementation, examples are EJBCA <http://www.ejbca.org> and
Insta Certifier <http://www.security.insta.fi>.

--- PATCH CONTENT ---

The patch contains the ASN1 definitions for structures used in the CMP protocol
(CMP from RFC 4210 and CRMF from RFC 4211) and functions to create and process 
them.

There is code to perform the most used CMP client operations over HTTP:
- initial request (ir)
- key update request (kur)
- certification request (cr)
- revocation request (rr)
- general message (genm)

In apps/cmp.c there is the code for providing an "openssl cmp" command to enable
using CMP from the command line.  The command "openssl cmp -help" will print out
a list of the available options and there is a man page for it available in
doc/apps/openssl_cmp.pod.

The CMP library code can be found under crypto/cmp and crypto/crmf.  There are
also POD documentation files under the cmp directory.  Apart from needed
additions to the makefiles and config scripts, as well as adding the relevant
error codes where needed, no other parts of OpenSSL are affected by the patch.

--- STANDARDS CONFORMITY ---

As this is only a CMP client-side implementation, the following also exclusively
takes client requirements into account!

RFC 4210's Appendix D specifies the profiles that must be supported by
conforming implementations.  From those, the implementation supports all but the
following:
- transmitting the end entity's private key in the request message
  (SYM_PENC_ALG, PROT_ENC_ALG, PROT_SYM_ALG)
- sending two certificate request messages within one CMP PKIMessage

The HTTP transport is done as per RFC 6712, with the exception that enabling
TLS is not yet implemented as there was no need for it.  In case that is needed
in the future it will be easy to add this using libcurl's already available
functionality.

Section 9.5 of 3GPP TS 33.310 details the CMP profile required for use in 3GPP
specified networks.  All of the requirements can be fulfilled when using the
implementation.  That includes also support for RFC 4210's appendix E.7 "In-Band
Initialization Using External Identity Certificate" and transfer of the trust
anchor in the CMP extraCert field.  As it is an addition to RFC 4210 and might
have security implications in certain circumstances, support for the latter must
be explicitly enabled by the user of the library/command.

--- LIBCURL FOR HTTP TRANSFER ---

CMP messages are transferred between client and server via HTTP (RFC 6712).  For
this libcurl, which is under an MIT/X derivate license, is utilized.  The code
relying on libcurl is not enabled by default in order to not add dependencies to
the default configuration.  To build in the CMP client functionality, one must
give the 'curl' option to the OpenSSL config script.  The default is to only
build the lower-level functionality of the CMP code.

The part of the CMP code using libcurl is linked into a separate library,
libcrypto_cmpseq, in order to deal with the circular dependency resulting from
libcurl using OpenSSL for TLS.  When needed one can first build the OpenSSL
libraries first (libssl and libcrypto), then curl, and then libcrypto_cmpseq.

So far, the changes to the Makefiles only permit libcrypto_smpseq to be built as
static library.

--- BUILDING AND TESTING THE PATCH ---

Apply the patch and build OpenSSL (example commands use the July 31th snapshot):

wget ftp://ftp.openssl.org/snapshot/openssl-SNAP-20130815.tar.gz
tar xzf openssl-SNAP-20130815.tar.gz
cd openssl-SNAP-20130815
patch -p1 < ../cmp.patch
./config    # append "curl" for using the system's libcurl for HTTP
make depend
make stacks
make

The HTTP protocol is provided through the code used for OCSP which we copied and
adapted to also provide the capability to traverse HTTP proxies.  If desired,
also the system's libcurl can be used for HTTP by doing "./config curl".

There are two public test servers available that you can try out the CMP
client with.  One is running the open-source EJBCA <http://www.ejbca.org>
and is provided and set up by PrimeKey, and the other one is the Insta
Certifier demo server provided by Insta <http://www.insta.fi>. Example
commands for both servers are provided below.

In the examples the user first generates a key and then performs the initial
request sequence to receive a certificate from the CA for this key.  Next, a new
key is generated, and we use the key update request message to get an updated
certificate for the new key.

There is a dissector for CMP included in Wireshark for those who wish to take a
closer look at the protocol data exchanged.

Note that if you're behind a proxy server you can set the address and port with
-proxy and -proxyport.  For more details, check the -help output or the manual
page.

Before executing the examples, go to the apps directory and create a directory
to store certificates in

$ cd openssl-SNAP-20130815/apps
$ mkdir certs


Commands for testing with EJBCA:

# get CA certificate
$ wget -O certs/3GPPCA.pem 
"http://ejbca-test.primekey.se:8080/ejbca/publicweb/webdist/certdist?cmd=cacert&issuer=CN%3d3GPP+CA%2cO%3dPrimeKey%2cC%3dSE&level=0";

# generate new key
$ ./openssl genrsa -out certs/cl_key.pem 2048

# do an initial request sequence
$ ./openssl cmp -cmd ir \
    -server ejbca-test.primekey.se:8080 \
    -path ejbca/publicweb/cmp \
    -srvcert certs/3GPPCA.pem \
    -user cmptest \
    -pass CMP-pwd \
    -newkey certs/cl_key.pem \
    -certout certs/cl_cert.pem \
    -subject "/CN=cmptest"

# generate an updated key for our cert
$ ./openssl genrsa -out certs/cl_new_key.pem 2048

# run the key update sequence
$ ./openssl cmp -cmd kur \
    -server ejbca-test.primekey.se:8080 \
    -path ejbca/publicweb/cmp \
    -srvcert certs/3GPPCA.pem \
    -key certs/cl_key.pem \
    -cert certs/cl_cert.pem \
    -newkey certs/cl_new_key.pem \
    -certout certs/cl_new_cert.pem


Commands for testing with Insta Certifier:

# generate new key
$ ./openssl genrsa -out certs/cl_key.pem 2048

# do an initial request sequence
$ ./openssl cmp -cmd ir \
    -server pki.certificate.fi:8700 \
    -path pkix/ \
    -user 3078 \
    -pass insta \
    -newkey certs/cl_key.pem \
    -certout certs/cl_cert.pem \
    -subject "/CN=CMP Test User" \
    -recipient "/C=FI/O=Insta Demo/CN=Insta Demo CA" \
    -extracertsout certs/cacert.pem

# generate an updated key for our cert
$ ./openssl genrsa -out certs/cl_new_key.pem 2048

# run the key update sequence
# Note: At the last time that was tested, the server didn't deliver certificates
#       but sent a 'waiting' status.  The client then starts polling (cf. RFC
#       4210's 5.3.22).  The polling goes on until the server delivers the
#       requested certificate.  The library would permit setting a timeout for
#       polling, but the 'openssl cmp' command does not make use of this
#       possibility.
$ ./openssl cmp -cmd kur \
    -server pki.certificate.fi:8700 \
    -path pkix/ \
    -key certs/cl_key.pem \
    -cert certs/cl_cert.pem \
    -newkey certs/cl_new_key.pem \
    -certout certs/cl_new_cert.pem \
    -srvcert certs/cacert.pem

########################## /UPDATED FULL PATCH DESCRIPTION ####################


______________________________________________________________________
OpenSSL Project                                 http://www.openssl.org
Development Mailing List                       [email protected]
Automated List Manager                           [email protected]

Reply via email to