Commit 2a3b52ea authored by David von Oheimb's avatar David von Oheimb Committed by Matt Caswell
Browse files

Certificate Management Protocol (CMP, RFC 4210) extension to OpenSSL


Also includes CRMF (RFC 4211) and HTTP transfer (RFC 6712)

CMP and CRMF API is added to libcrypto, and the "cmp" app to the openssl CLI.
Adds extensive man pages and tests.  Integration into build scripts.

Incremental pull request based on OpenSSL commit 1362190b of 2018-09-26

1st chunk: CRMF API (include/openssl/crmf.h) and its documentation (reviewed)

Reviewed-by: default avatarBernd Edlinger <bernd.edlinger@hotmail.de>
Reviewed-by: default avatarMatt Caswell <matt@openssl.org>
(Merged from https://github.com/openssl/openssl/pull/7328)
parent eef721b0
Loading
Loading
Loading
Loading
+66 −0
Original line number Diff line number Diff line
=pod

=head1 NAME

OSSL_CRMF_MSG_get0_tmpl,
OSSL_CRMF_CERTTEMPLATE_get0_serialNumber,
OSSL_CRMF_CERTTEMPLATE_get0_issuer,
OSSL_CRMF_ENCRYPTEDVALUE_get1_encCert,
OSSL_CRMF_MSG_get_certReqId
- functions reading from CRMF CertReqMsg structures

=head1 SYNOPSIS

 #include <openssl/crmf.h>

 OSSL_CRMF_CERTTEMPLATE *OSSL_CRMF_MSG_get0_tmpl(const OSSL_CRMF_MSG *crm);
 ASN1_INTEGER
     *OSSL_CRMF_CERTTEMPLATE_get0_serialNumber(OSSL_CRMF_CERTTEMPLATE *tmpl);
 X509_NAME *OSSL_CRMF_CERTTEMPLATE_get0_issuer(OSSL_CRMF_CERTTEMPLATE *tmpl);

 X509 *OSSL_CRMF_ENCRYPTEDVALUE_get1_encCert(OSSL_CRMF_ENCRYPTEDVALUE *ecert,
                                             EVP_PKEY *pkey);

 int OSSL_CRMF_MSG_get_certReqId(OSSL_CRMF_MSG *crm);


=head1 DESCRIPTION

OSSL_CRMF_MSG_get0_tmpl() retrieves the certificate template of B<crm>.

OSSL_CRMF_CERTTEMPLATE_get0_serialNumber() retrieves the serialNumber of the
given certificate template B<tmpl>.

OSSL_CRMF_CERTTEMPLATE_get0_issuer() retrieves the issuer name of the
given certificate template B<tmpl>.

OSSL_CRMF_ENCRYPTEDVALUE_get1_encCert() decrypts the certificate in the given
encryptedValue B<ecert>, using the private key B<pkey>.
This is needed for the indirect PoP method as in RFC 4210 section 5.2.8.2.
The function returns the decrypted certificate as a copy, leaving its ownership
with the caller, who is responsible for freeing it.

OSSL_CRMF_MSG_get_certReqId() retrieves the certReqId of B<crm>.


=head1 RETURN VALUES

OSSL_CRMF_MSG_get_certReqId() returns the certificate request ID as a
non-negative integer or -1 on error.

All other functions return a pointer with the intended result or NULL on error.

=head1 SEE ALSO

B<RFC 4211>

=head1 COPYRIGHT

Copyright 2007-2018 The OpenSSL Project Authors. All Rights Reserved.

Licensed under the OpenSSL license (the "License").  You may not use
this file except in compliance with the License.  You can obtain a copy
in the file LICENSE in the source distribution or at
L<https://www.openssl.org/source/license.html>.

=cut
+105 −0
Original line number Diff line number Diff line
=pod

=head1 NAME

OSSL_CRMF_MSG_set1_regCtrl_regToken,
OSSL_CRMF_MSG_set1_regCtrl_authenticator,
OSSL_CRMF_MSG_PKIPublicationInfo_push0_SinglePubInfo,
OSSL_CRMF_MSG_set0_SinglePubInfo,
OSSL_CRMF_MSG_set_PKIPublicationInfo_action,
OSSL_CRMF_MSG_set1_regCtrl_pkiPublicationInfo,
OSSL_CRMF_MSG_set1_regCtrl_protocolEncrKey,
OSSL_CRMF_MSG_set1_regCtrl_oldCertID,
OSSL_CRMF_CERTID_gen
- functions setting CRMF Registration Controls

=head1 SYNOPSIS

 #include <openssl/crmf.h>

 int OSSL_CRMF_MSG_set1_regCtrl_regToken(OSSL_CRMF_MSG *msg,
                                         const ASN1_UTF8STRING *tok);
 int OSSL_CRMF_MSG_set1_regCtrl_authenticator(OSSL_CRMF_MSG *msg,
                                              const ASN1_UTF8STRING *auth);
 int OSSL_CRMF_MSG_PKIPublicationInfo_push0_SinglePubInfo(
                                  OSSL_CRMF_PKIPUBLICATIONINFO *pi,
                                  OSSL_CRMF_SINGLEPUBINFO *spi);
 int OSSL_CRMF_MSG_set0_SinglePubInfo(OSSL_CRMF_SINGLEPUBINFO *spi,
                                      int method, GENERAL_NAME *nm);
 int OSSL_CRMF_MSG_set_PKIPublicationInfo_action(
                                  OSSL_CRMF_PKIPUBLICATIONINFO *pi, int action);
 int OSSL_CRMF_MSG_set1_regCtrl_pkiPublicationInfo(OSSL_CRMF_MSG *msg,
                                        const OSSL_CRMF_PKIPUBLICATIONINFO *pi);
 int OSSL_CRMF_MSG_set1_regCtrl_protocolEncrKey(OSSL_CRMF_MSG *msg,
                                                const X509_PUBKEY *pubkey);
 int OSSL_CRMF_MSG_set1_regCtrl_oldCertID(OSSL_CRMF_MSG *msg,
                                          const OSSL_CRMF_CERTID *cid);
 OSSL_CRMF_CERTID *OSSL_CRMF_CERTID_gen(const X509_NAME *issuer,
                                        const ASN1_INTEGER *serial);

=head1 DESCRIPTION

OSSL_CRMF_MSG_set1_regCtrl_regToken() sets the regToken control in the given
B<msg> copying the given B<tok> as value. See RFC 4211, section 6.1.

OSSL_CRMF_MSG_set1_regCtrl_authenticator() sets the authenticator control in
the given B<msg> copying the given B<auth> as value. See RFC 4211, section 6.2.

OSSL_CRMF_MSG_PKIPublicationInfo_push0_SinglePubInfo() pushes the given B<spi>
to B<si>. Consumes the B<spi> pointer.

OSSL_CRMF_MSG_set0_SinglePubInfo() sets given B<method> and PubLoction B<nm> to
B<spi>.  PubLocation is optional, and therefore B<nm> may be NULL. Consumes the
B<nm> pointer.
Available methods are:
 # define OSSL_CRMF_PUB_METHOD_DONTCARE 0
 # define OSSL_CRMF_PUB_METHOD_X500     1
 # define OSSL_CRMF_PUB_METHOD_WEB      2
 # define OSSL_CRMF_PUB_METHOD_LDAP     3

OSSL_CRMF_MSG_set_PKIPublicationInfo_action() sets the action in the given B<pi>
using the given B<action> as value. See RFC 4211, section 6.3.
Available actions are:
 # define OSSL_CRMF_PUB_ACTION_DONTPUBLISH   0
 # define OSSL_CRMF_PUB_ACTION_PLEASEPUBLISH 1

OSSL_CRMF_MSG_set1_regCtrl_pkiPublicationInfo() sets the pkiPulicationInfo
control in the given B<msg> copying the given B<tok> as value. See RFC 4211,
section 6.3.

OSSL_CRMF_MSG_set1_regCtrl_protocolEncrKey() sets the protocolEncrKey control in
the given B<msg> copying the given B<pubkey> as value. See RFC 4211, section 6.6.

OSSL_CRMF_MSG_set1_regCtrl_oldCertID() sets the oldCertID control in the given
B<msg> copying the given B<cid> as value. See RFC 4211, section 6.5.

OSSL_CRMF_CERTID_gen produces an OSSL_CRMF_CERTID_gen structure copying the
given B<issuer> name and B<serial> number.

=head1 RETURN VALUES

OSSL_CRMF_CERTID_gen returns a pointer to the resulting structure
or NULL on error.

All other functions return 1 on success, 0 on error.

=head1 NOTES

A function OSSL_CRMF_MSG_set1_regCtrl_pkiArchiveOptions() for setting an
Archive Options Control is not yet implemented due to missing features to
create the needed OSSL_CRMF_PKIARCHIVEOPTINS content.

=head1 SEE ALSO

RFC 4211

=head1 COPYRIGHT

Copyright 2007-2018 The OpenSSL Project Authors. All Rights Reserved.

Licensed under the OpenSSL license (the "License").  You may not use
this file except in compliance with the License.  You can obtain a copy
in the file LICENSE in the source distribution or at
L<https://www.openssl.org/source/license.html>.

=cut
+49 −0
Original line number Diff line number Diff line
=pod

=head1 NAME

OSSL_CRMF_MSG_set1_regInfo_utf8Pairs,
OSSL_CRMF_MSG_set1_regInfo_certReq
- functions setting CRMF Registration Info

=head1 SYNOPSIS

 #include <openssl/crmf.h>

 int OSSL_CRMF_MSG_set1_regInfo_utf8Pairs(OSSL_CRMF_MSG *msg,
                                          const ASN1_UTF8STRING *utf8pairs);
 int OSSL_CRMF_MSG_set1_regInfo_certReq(OSSL_CRMF_MSG *msg,
                                        const OSSL_CRMF_CERTREQUEST *cr);

=head1 DESCRIPTION

OSSL_CRMF_MSG_set1_regInfo_utf8Pairs() adds a copy of the given B<utf8pairs>
value as utf8Pairs regInfo to the given B<msg>. See RFC 4211 section 7.1.

OSSL_CRMF_MSG_set1_regInfo_certReq() adds a copy of the given B<cr> value
as certReq regInfo to the given B<msg>. See RFC 4211 section 7.2.

=head1 RETURN VALUES

All functions return 1 on success, 0 on error.

=head1 NOTES

Calling these functions multiple times adds multiple instances of the respective
control to the regInfo structure of the given B<msg>. While RFC 4211 expects
multiple utf8Pairs in one regInfo structure, it does not allow multiple certReq.

=head1 SEE ALSO

RFC 4211

=head1 COPYRIGHT

Copyright 2007-2018 The OpenSSL Project Authors. All Rights Reserved.

Licensed under the OpenSSL license (the "License").  You may not use
this file except in compliance with the License.  You can obtain a copy
in the file LICENSE in the source distribution or at
L<https://www.openssl.org/source/license.html>.

=cut
+103 −0
Original line number Diff line number Diff line
=pod

=head1 NAME

OSSL_CRMF_MSG_set_validity,
OSSL_CRMF_MSG_set_certReqId,
OSSL_CRMF_CERTTEMPLATE_fill,
OSSL_CRMF_MSG_set0_extensions,
OSSL_CRMF_MSG_push0_extension,
OSSL_CRMF_MSG_create_popo,
OSSL_CRMF_MSGS_verify_popo
- functions populating and verifying CRMF CertReqMsg structures

=head1 SYNOPSIS

 #include <openssl/crmf.h>

 int OSSL_CRMF_MSG_set_validity(OSSL_CRMF_MSG *crm, time_t from, time_t to);

 int OSSL_CRMF_MSG_set_certReqId(OSSL_CRMF_MSG *crm, const int rid);

 int OSSL_CRMF_CERTTEMPLATE_fill(OSSL_CRMF_CERTTEMPLATE *tmpl,
                                 const EVP_PKEY *pubkey,
                                 const X509_NAME *subject,
                                 const X509_NAME *issuer,
                                 const ASN1_INTEGER *serial);

 int OSSL_CRMF_MSG_set0_extensions(OSSL_CRMF_MSG *crm,
                                   X509_EXTENSIONS *exts);

 int OSSL_CRMF_MSG_push0_extension(OSSL_CRMF_MSG *crm,
                                   const X509_EXTENSION *ext);

 int OSSL_CRMF_MSG_create_popo(OSSL_CRMF_MSG *crm, const EVP_PKEY *pkey,
                               int dgst, int ppmtd);

 int OSSL_CRMF_MSGS_verify_popo(const OSSL_CRMF_MSGS *reqs,
                                int rid, int acceptRAVerified);

=head1 DESCRIPTION

OSSL_CRMF_MSG_set_validity() sets B<from> as notBefore and B<to> as notAfter
as the validity in the certTemplate of B<crm>.

OSSL_CRMF_MSG_set_certReqId() sets B<rid> as the certReqId of B<crm>.

OSSL_CRMF_CERTTEMPLATE_fill() sets those fields of the certTemplate B<tmpl>
for which non-NULL values are provided: B<pubkey>, B<subject>, B<issuer>,
and/or B<serial>. The arguments are not consumed.

OSSL_CRMF_MSG_set0_extensions() sets B<exts> as the extensions in the
certTemplate of B<crm>. Consumes B<exts>.

OSSL_CRMF_MSG_push0_extension() pushes the X509 extension B<ext> to the
extensions in the certTemplate of B<crm>.  Consumes B<ext>.

OSSL_CRMF_MSG_create_popo() creates and sets the Proof-of-Possession (POP)
according to the method B<ppmtd> for B<pkey> to B<crm>. In case the method is
OSSL_CRMF_POPO_SIGNATURE, POP is calculated using the B<dgst>.

B<ppmtd> can be one of the following:

=over 8

=item * OSSL_CRMF_POPO_NONE       - RFC 4211, section 4, POP field omitted.
CA/RA uses out-of-band method to verify POP. Note that servers may fail in this
case, resulting for instance in HTTP error code 500 (Internal error).

=item * OSSL_CRMF_POPO_RAVERIFIED - RFC 4211, section 4, explicit indication
that the RA has already verified the POP.

=item * OSSL_CRMF_POPO_SIGNATURE  - RFC 4211, section 4.1, only case 3 supported
so far.

=item * OSSL_CRMF_POPO_KEYENC     - RFC 4211, section 4.2, only indirect method
(subsequentMessage/enccert) supported,
challenge-response exchange (challengeResp) not yet supported.

=item * OSSL_CRMF_POPO_KEYAGREE   - RFC 4211, section 4.3, not yet supported.

=back

OSSL_CRMF_MSGS_verify_popo verifies the Proof-of-Possession of the request with
the given B<rid> in the list of B<reqs>. Optionally accepts RAVerified.

=head1 RETURN VALUES

All functions return 1 on success, 0 on error.

=head1 SEE ALSO

RFC 4211

=head1 COPYRIGHT

Copyright 2007-2018 The OpenSSL Project Authors. All Rights Reserved.

Licensed under the OpenSSL license (the "License").  You may not use
this file except in compliance with the License.  You can obtain a copy
in the file LICENSE in the source distribution or at
L<https://www.openssl.org/source/license.html>.

=cut
+78 −0
Original line number Diff line number Diff line
=pod

=head1 NAME

OSSL_CRMF_pbm_new,
OSSL_CRMF_pbmp_new
- functions for producing Password-Based MAC (PBM)

=head1 SYNOPSIS

  #include <openssl/crmf.h>

  int OSSL_CRMF_pbm_new(const OSSL_CRMF_PBMPARAMETER *pbmp,
                        const unsigned char *msg, size_t msglen,
                        const unsigned char *sec, size_t seclen,
                        unsigned char **mac, unsigned int *maclen);

  OSSL_CRMF_PBMPARAMETER *OSSL_CRMF_pbmp_new(size_t saltlen, int owfnid,
                                             int itercnt, int macnid);

=head1 DESCRIPTION

OSSL_CRMF_pbm_new() generates a PBM (Password-Based MAC) based on given PBM
parameters B<pbmp>, message B<msg>, and secret B<sec>, along with the respective
lengths B<msglen> and B<seclen>. Will write the adddress of the newly allocated
MAC via the B<mac> reference parameter and the length via the B<maclen> reference
parameter. Any previous pointer referred to by B<mac> will be freed if not NULL.

The iteration count must be at least 100, as stipulated by RFC 4211, and is
limited to at most 100000 to avoid DoS through manipulated or otherwise
malformed input.

OSSL_CRMF_pbmp_new() initializes and returns a new PBMParameter
structure with new a random salt of given length B<saltlen>, OWF (one-way
function) NID B<owfnid>, iteration count B<itercnt>, and MAC NID B<macnid>.

=head1 NOTES

The OWF (one-way function) and for the MAC (message authentication code) may be
any with a NID defined in B<openssl/objects.h>,
which also should include NID_hmac_sha1 which is specified by RFC 4210.

RFC 4210 recommends that the salt SHOULD be at least 8 bytes (64 bits) long.

=head1 RETURN VALUES

OSSL_CRMF_pbm_new() returns 1 on success, 0 on error.

OSSL_CRMF_pbmp_new() returns a new and initialized OSSL_CRMF_PBMPARAMETER
structure, or NULL on error.

=head1 EXAMPLE

 OSSL_CRMF_PBMPARAMETER *pbm = NULL;
 unsigned char *msg = "Hello";
 unsigend char *sec = "SeCrEt";
 unsigend char *mac = NULL;
 unsigend int maclen;

 if ((pbm = OSSL_CRMF_pbmp_new(16, NID_sha256, 500, NID_hmac_sha1) == NULL))
     goto err;
 if (!OSSL_CRMF_pbm_new(pbm, msg, 5, sec, 6, &mac, &maclen))
     goto err;

=head1 SEE ALSO

RFC 4211 section 4.4

=head1 COPYRIGHT

Copyright 2007-2018 The OpenSSL Project Authors. All Rights Reserved.

Licensed under the OpenSSL license (the "License").  You may not use
this file except in compliance with the License.  You can obtain a copy
in the file LICENSE in the source distribution or at
L<https://www.openssl.org/source/license.html>.

=cut
Loading