Merge lp:~hipl-core/hipl/certificate-exchange into lp:hipl
- certificate-exchange
- Merge into trunk
Status: | Superseded |
---|---|
Proposed branch: | lp:~hipl-core/hipl/certificate-exchange |
Merge into: | lp:hipl |
Diff against target: |
3147 lines (+1398/-1002) 33 files modified
Makefile.am (+5/-1) configure.ac (+2/-0) doc/HOWTO.xml.in (+75/-0) hipd/cert.c (+155/-81) hipd/input.c (+0/-1) hipd/output.c (+0/-1) hipfw/cert.c (+167/-528) hipfw/cert.h (+14/-24) hipfw/conntrack.c (+20/-9) hipfw/hipfw.c (+5/-7) hipfw/hipfw.conf (+1/-0) hipfw/hipfw_defines.h (+0/-1) hipfw/main.c (+2/-1) hipfw/pisa_cert.c (+0/-205) hipfw/pisa_cert.h (+0/-47) hipfw/rule_management.c (+23/-0) hipfw/rule_management.h (+1/-0) lib/core/builder.c (+12/-5) lib/core/builder.h (+7/-9) lib/core/cert.c (+286/-0) lib/core/cert.h (+51/-0) lib/core/certtools.c (+5/-5) lib/core/conf.c (+132/-4) lib/core/protodefs.h (+14/-0) modules/cert/hipd/cert.c (+169/-49) modules/cert/hipd/cert.h (+7/-20) modules/cert/module_info.xml (+23/-0) test/check_lib_core.c (+1/-0) test/lib/core/cert.c (+189/-0) test/lib/core/test_cert.pem (+15/-0) test/lib/core/test_key.pem (+15/-0) test/lib/core/test_suites.h (+1/-0) tools/hipl_autobuild.sh (+1/-4) |
To merge this branch: | bzr merge lp:~hipl-core/hipl/certificate-exchange |
Related bugs: |
Reviewer | Review Type | Date Requested | Status |
---|---|---|---|
Miika Komu | Approve | ||
Review via email: mp+96762@code.launchpad.net |
This proposal supersedes a proposal from 2012-03-02.
This proposal has been superseded by a proposal from 2012-03-09.
Commit message
Description of the change
Here is the updated version with trunk freshly merged in as well as a number of fixes.
Miika Komu (miika-iki) wrote : Posted in a previous version of this proposal | # |
Miika Komu (miika-iki) wrote : Posted in a previous version of this proposal | # |
Forgot to mention:
Text conflict in hipd/cert.c
Text conflict in test/check_
Diego Biurrun (diego-biurrun) wrote : Posted in a previous version of this proposal | # |
On Fri, Mar 02, 2012 at 10:23:21PM +0000, Miika Komu wrote:
> Review: Needs Information
>
> Can you remind why the PISA stuff was removed?
I'm not sure what you mean by PISA stuff here. We renamed everything
labeled PISA because it really is more generic functionality that can
be used outside of the PISA project.
Diego
Diego Biurrun (diego-biurrun) wrote : Posted in a previous version of this proposal | # |
On Sat, Mar 03, 2012 at 07:15:22AM +0000, Miika Komu wrote:
> Forgot to mention:
>
> Text conflict in hipd/cert.c
> Text conflict in test/check_
Yes, I did not bother to merge the last two commits from trunk.
I can redo the merge request from a branch with latest trunk merged
tomorrow if that is preferred. But the conflicts should not make
much of a difference for reviewing.
Diego
Miika Komu (miika-iki) wrote : Posted in a previous version of this proposal | # |
Works for me.
René Hummen (rene-hummen) wrote : Posted in a previous version of this proposal | # |
The code to be merged has been tested and worked fine. Also the code looks ok. A few minor issues below.
On 02.03.2012, at 19:08, Diego Biurrun wrote:
> Diego Biurrun has proposed merging lp:~hipl-core/hipl/certificate-exchange into lp:hipl.
> === modified file 'hipfw/main.c'
> --- hipfw/main.c 2011-11-25 13:52:20 +0000
> +++ hipfw/main.c 2012-03-02 18:07:40 +0000
> @@ -37,14 +37,16 @@
>
> #include <stdio.h>
> #include <stdlib.h>
> +#include <string.h>
> #include <unistd.h>
> #include <sys/types.h>
>
> #include "lib/core/
> #include "lib/core/debug.h"
> #include "lib/core/util.h"
> +#include "cert.h"
> +#include "conntrack.h"
> #include "hipfw.h"
> -#include "conntrack.h"
> #include "midauth.h"
Why was cert.h included here? -> Removed in new revision.
> === modified file 'modules/
> --- modules/
> +++ modules/
> @@ -57,6 +57,7 @@
> #include "lib/core/prefix.h"
> #include "lib/core/state.h"
> #include "lib/core/
> +#include "modules/
> #include "update_builder.h"
> #include "update_locator.h"
> #include "update_
Why was this include added? -> Removed in new revision.
--
Dipl.-Inform. Rene Hummen, Ph.D. Student
Chair of Communication and Distributed Systems
RWTH Aachen University, Germany
tel: +49 241 80 20772
web: http://
Diego Biurrun (diego-biurrun) wrote : Posted in a previous version of this proposal | # |
review needs-fixing
On Fri, Mar 02, 2012 at 06:08:20PM +0000, Diego Biurrun wrote:
> Diego Biurrun has proposed merging lp:~hipl-core/hipl/certificate-exchange into lp:hipl.
>
> --- hipd/cert.c 2012-03-01 14:06:24 +0000
> +++ hipd/cert.c 2012-03-02 18:07:40 +0000
The functions in this file are HUUUUGE - IMO this needs some refactoring.
> @@ -682,89 +688,109 @@
> +
> + /* Were we sent a timestamp which indicates a requested cert validity? */
> + validity_param = hip_get_param(msg, HIP_PARAM_UINT);
> +
> + if (validity_param) {
> + const uint32_t valid_until_n = *(const uint32_t *) hip_get_
> + const uint32_t valid_until_h = ntohl(valid_
Gah, pointer type punning.
> @@ -797,33 +821,67 @@
> +
> + X509_get_
> + X509_get_
> +
> + {
> + const time_t now = time(NULL);
> + time_t starttime = 0;
> + time_t endtime = 0;
> + time_t *starttime_p = NULL;
> + time_t *endtime_p = NULL;
The block braces are unnecessary, we allow mixed declarations and
statements.
> switch (algo) {
> case HIP_HI_RSA:
> - HIP_IFEL(
> + HIP_IFEL(
> "Failed to convert RSA to EVP_PKEY\n");
> HIP_IFEL(
> "Failed to set public key of the certificate\n");
> break;
> case HIP_HI_DSA:
> - HIP_IFEL(
> + HIP_IFEL(
> "Failed to convert DSA to EVP_PKEY\n");
peer_pub_key is a void*, the casts are unnecessary.
> @@ -926,7 +984,25 @@
>
> + switch (host_id-
> + case HIP_HI_RSA:
> + HIP_IFEL(
> + "Failed to convert RSA to EVP_PKEY\n");
> + break;
> + case HIP_HI_DSA:
> + HIP_IFEL(
> + "Failed to convert DSA to EVP_PKEY\n");
> + break;
same here
> --- hipfw/pisa.c 2011-11-25 13:52:20 +0000
> +++ hipfw/cert.c 2012-03-02 18:07:40 +0000
> @@ -25,551 +25,192 @@
> +#include "rule_management.h"
> +#include "cert.h"
> +
> +// runtime configuration
> +int use_cert = false;
This could be static.
> +const char *root_certifica
This is unused.
> --- lib/core/builder.c 2012-03-01 14:06:24 +0000
> +++ lib/core/builder.c 2012-03-02 18:07:40 +0000
> @@ -3388,16 +3395,21 @@
> int hip_build_
> {
> + int err = -1;
> + struct hip_cert_x509_resp subj = { 0 };
> +
> + if (len > 0 && (unsigned int) len <= sizeof(subj.der)) {
> + hip_set_
> + hip_calc_
> + sizeof(struct hip_cert...
Diego Biurrun (diego-biurrun) wrote : Posted in a previous version of this proposal | # |
On Thu, Mar 08, 2012 at 06:41:47PM +0100, Diego Biurrun wrote:
> review needs-fixing
It still needs fixing, I'm just commenting on the issues I addressed.
> On Fri, Mar 02, 2012 at 06:08:20PM +0000, Diego Biurrun wrote:
> > Diego Biurrun has proposed merging lp:~hipl-core/hipl/certificate-exchange into lp:hipl.
> >
> > --- hipd/cert.c 2012-03-01 14:06:24 +0000
> > +++ hipd/cert.c 2012-03-02 18:07:40 +0000
> > @@ -682,89 +688,109 @@
> > +
> > + /* Were we sent a timestamp which indicates a requested cert validity? */
> > + validity_param = hip_get_param(msg, HIP_PARAM_UINT);
> > +
> > + if (validity_param) {
> > + const uint32_t valid_until_n = *(const uint32_t *) hip_get_
> > + const uint32_t valid_until_h = ntohl(valid_
>
> Gah, pointer type punning.
Fixed.
> > @@ -797,33 +821,67 @@
> > +
> > + X509_get_
> > + X509_get_
> > +
> > + {
> > + const time_t now = time(NULL);
> > + time_t starttime = 0;
> > + time_t endtime = 0;
> > + time_t *starttime_p = NULL;
> > + time_t *endtime_p = NULL;
>
> The block braces are unnecessary, we allow mixed declarations and
> statements.
Fixed.
Apparently Christoph's intention here was to reduce the scope of the
variables and possibly split the function into pieces along this line.
So if somebody wants to step forward and do that.. :)
> > switch (algo) {
> > case HIP_HI_RSA:
> > - HIP_IFEL(
> > + HIP_IFEL(
> > "Failed to convert RSA to EVP_PKEY\n");
> > HIP_IFEL(
> > "Failed to set public key of the certificate\n");
> > break;
> > case HIP_HI_DSA:
> > - HIP_IFEL(
> > + HIP_IFEL(
> > "Failed to convert DSA to EVP_PKEY\n");
>
> peer_pub_key is a void*, the casts are unnecessary.
Fixed.
> > @@ -926,7 +984,25 @@
> >
> > + switch (host_id-
> > + case HIP_HI_RSA:
> > + HIP_IFEL(
> > + "Failed to convert RSA to EVP_PKEY\n");
> > + break;
> > + case HIP_HI_DSA:
> > + HIP_IFEL(
> > + "Failed to convert DSA to EVP_PKEY\n");
> > + break;
>
> same here
Fixed.
> > --- hipfw/pisa.c 2011-11-25 13:52:20 +0000
> > +++ hipfw/cert.c 2012-03-02 18:07:40 +0000
> > @@ -25,551 +25,192 @@
> > +#include "rule_management.h"
> > +#include "cert.h"
> > +
> > +// runtime configuration
> > +int use_cert = false;
>
> This could be static.
Fixed.
> > +const char *root_certifica
>
> This is unused.
Fixed.
> > --- lib/core/builder.c 2012-03-01 14:06:24 +0000
> > +++ lib/core/builder.c 2012-03-02 18:07:40 +0000
> > @@ -3388,16 +3395,21 @@
> ...
- 6124. By Diego Biurrun
-
Merge trunk again after landing of exponential backoff branch.
Diego Biurrun (diego-biurrun) wrote : Posted in a previous version of this proposal | # |
On Thu, Mar 08, 2012 at 06:41:47PM +0100, Diego Biurrun wrote:
> review needs-fixing
>
> On Fri, Mar 02, 2012 at 06:08:20PM +0000, Diego Biurrun wrote:
> > Diego Biurrun has proposed merging lp:~hipl-core/hipl/certificate-exchange into lp:hipl.
> >
> > --- test/lib/
> > +++ test/lib/
> > @@ -0,0 +1,189 @@
> > +
> > +START_
> > +{
> > + int len = 0;
> > + X509 *cert = NULL;
> > + X509 *cert_decoded = NULL;
> > + unsigned char *buf = NULL;
> > +
> > + HIP_DEBUG("Test DER en/decoding of X509 certificates.\n");
> > +
> > + fail_unless((cert = cert_load_
> > + ENCODING_
> > + NULL);
> > + fail_unless((len = cert_X509_
> > + fail_unless(
> > + fail_unless(
> > +
> > + fail_unless((len = cert_X509_
> > + fail_unless((len = cert_X509_
> > + fail_unless((len = cert_X509_
> > +
> > + fail_unless(
> > + fail_unless(
> > + fail_unless(
> > + fail_unless(
> > +
> > + X509_free(cert);
> > + X509_free(
>
> buf does not need to be freed?
>
> > +START_
> > +{
> > + int err = 0;
> > + RSA *rsa = NULL;
> > + X509 *cert = NULL;
> > + EVP_PKEY *pkey = NULL;
> > +
> > + HIP_DEBUG("Test matching of public keys.\n");
> > +
> > + fail_unless((err = load_rsa_
> > + fail_unless((cert = cert_load_
> > + ENCODING_
> > + NULL);
> > + pkey = EVP_PKEY_new();
> > + EVP_PKEY_
> > + fail_unless((err = cert_match_
> > +
> > + fail_unless((err = cert_match_
> > + fail_unless((err = cert_match_
> > + fail_unless((err = cert_match_
> > +
> > + EVP_PKEY_
> > + X509_free(cert);
>
> RSA_free(rsa);
>
> .. at least if the doxy of load_rsa_
>
> > +START_
> > +{
> > + int err = 0;
> > + X509 *cert = NULL;
> > + STACK_OF(X509) * chain = NULL;
> > +
> > + HIP_DEBUG("Test verification of certificate chains.\n");
> > +
> > + fail_unless((cert = cert_load_
> > + ENCODING_
> > + NULL);
> > + ...
Diego Biurrun (diego-biurrun) wrote : Posted in a previous version of this proposal | # |
On Thu, Mar 08, 2012 at 06:41:47PM +0100, Diego Biurrun wrote:
> review needs-fixing
This branch still has serious issues, even after the number of fixes
I applied in the last few days. I'll ping the areas that I have
questions about and remain unfixed below.
> On Fri, Mar 02, 2012 at 06:08:20PM +0000, Diego Biurrun wrote:
> > Diego Biurrun has proposed merging lp:~hipl-core/hipl/certificate-exchange into lp:hipl.
> >
> > --- hipd/cert.c 2012-03-01 14:06:24 +0000
> > +++ hipd/cert.c 2012-03-02 18:07:40 +0000
>
> The functions in this file are HUUUUGE - IMO this needs some refactoring.
Any volunteers? The original authors maybe? I still don't really
understand the "big picture" of this branch.
> > --- lib/core/cert.c 1970-01-01 00:00:00 +0000
> > +++ lib/core/cert.c 2012-03-02 18:07:40 +0000
> > @@ -0,0 +1,292 @@
> > +/**
> > + * This function encodes the given certificate to its DER encoding for
> > + * transmission over the wire. The encoded certificate is written to @ *buf.
> > + *
> > + * @param cert the certificate to encode
> > + * @param buf the output is written here
> > + *
> > + * @return the length of the encoded data
> > + *
> > + * @note: The encoded data is in binary form and may contain embedded zeroes.
> > + * Functions such as strlen() will not return the correct length of the
> > + * encoded structure. Therefore length value returned by this function
> > + * should always be used.
> > + */
> > +int cert_X509_
> > +{
> > + int len;
> > +
> > + if (!cert) {
> > + HIP_ERROR("Cannot encode NULL-certificat
> > + return -1;
> > + }
> > + if (!buf) {
> > + HIP_ERROR("Cannot create output buffer at NULL-pointer.\n");
> > + return -1;
> > + }
> > +
> > + *buf = NULL;
> > + len = i2d_X509(cert, buf);
> > +
> > + if (len < 0) {
> > + HIP_ERROR("Could not DER-encode the given certificate.\n");
> > + return -1;
> > + }
> > + return len;
> > +}
>
> The
>
> *buf = NULL;
>
> assignment looks suspicious to me, can somebody explain it?
Please somebody enlighten us.
> > +/**
> > + * Load a X509 certificate from @ file. If @ file contains more
> > + * than one certificate, the certificate at the top of the file is
> > + * returned.
> > + *
> > + * @param file the file to load the certficate from
> > + * @param fmt the input format of the certificate
> > + *
> > + * @return a X509 certificate on success, NULL on error
> > + */
> > +X509 *cert_load_
> > + enum encoding_format fmt)
> > +{
> > + FILE *fp = NULL;
> > + X509 *cert = NULL;
> > +
> > + if (!file) {
> > + HIP_ERROR("Cannot read certificate from NULL-filename.\n");
> > + return NULL;
> > + }
> > +
> > + fp = fopen(file, "rb");
> > + if (!fp) {
> > + HIP_ERROR("Could not open file for reading: %s\n", file);
> > + return NULL;
> > + }
> > +
> > + if (fmt == ENCODING_
> > + cert = PEM_read_X509(fp, NULL, NULL, NULL);
> > + } else if (fmt == ENCODING_
Miika Komu (miika-iki) wrote : Posted in a previous version of this proposal | # |
Hi,
On 03/12/2012 10:29 PM, Diego Biurrun wrote:
>> > On Fri, Mar 02, 2012 at 06:08:20PM +0000, Diego Biurrun wrote:
>>> > > Diego Biurrun has proposed merging lp:~hipl-core/hipl/certificate-exchange into lp:hipl.
>>> > >
>>> > > --- hipd/cert.c 2012-03-01 14:06:24 +0000
>>> > > +++ hipd/cert.c 2012-03-02 18:07:40 +0000
>> >
>> > The functions in this file are HUUUUGE - IMO this needs some refactoring.
> Any volunteers? The original authors maybe? I still don't really
> understand the "big picture" of this branch.
not volunteering, but asking if the merge make things worse or keep them
function length the same? If the length is the same, this should be
handled separately.
Diego Biurrun (diego-biurrun) wrote : Posted in a previous version of this proposal | # |
On Mon, Mar 12, 2012 at 09:29:29PM +0100, Diego Biurrun wrote:
> On Thu, Mar 08, 2012 at 06:41:47PM +0100, Diego Biurrun wrote:
> > On Fri, Mar 02, 2012 at 06:08:20PM +0000, Diego Biurrun wrote:
> > > Diego Biurrun has proposed merging lp:~hipl-core/hipl/certificate-exchange into lp:hipl.
> > >
> > > --- hipd/cert.c 2012-03-01 14:06:24 +0000
> > > +++ hipd/cert.c 2012-03-02 18:07:40 +0000
> >
> > The functions in this file are HUUUUGE - IMO this needs some refactoring.
>
> Any volunteers? The original authors maybe? I still don't really
> understand the "big picture" of this branch.
Left for never^wlater.
> > > --- lib/core/cert.c 1970-01-01 00:00:00 +0000
> > > +++ lib/core/cert.c 2012-03-02 18:07:40 +0000
> > > @@ -0,0 +1,292 @@
> > > +/**
> > > + * Load a X509 certificate from @ file. If @ file contains more
> > > + * than one certificate, the certificate at the top of the file is
> > > + * returned.
> > > + *
> > > + * @param file the file to load the certficate from
> > > + * @param fmt the input format of the certificate
> > > + *
> > > + * @return a X509 certificate on success, NULL on error
> > > + */
> > > +X509 *cert_load_
> > > + enum encoding_format fmt)
> > > +{
> > > + FILE *fp = NULL;
> > > + X509 *cert = NULL;
> > > +
> > > + if (!file) {
> > > + HIP_ERROR("Cannot read certificate from NULL-filename.\n");
> > > + return NULL;
> > > + }
> > > +
> > > + fp = fopen(file, "rb");
> > > + if (!fp) {
> > > + HIP_ERROR("Could not open file for reading: %s\n", file);
> > > + return NULL;
> > > + }
> > > +
> > > + if (fmt == ENCODING_
> > > + cert = PEM_read_X509(fp, NULL, NULL, NULL);
> > > + } else if (fmt == ENCODING_
> > > + cert = d2i_X509_fp(fp, NULL);
> > > + } else {
> > > + HIP_ERROR("Invalid encoding format %i \n", fmt);
> > > + return NULL;
> > > + }
> >
> > switch/case? Might more formats get added here?
>
> Anybody?
Converted to switch/case, looks nicer at least.
> > > + if (fclose(fp)) {
> > > + HIP_ERROR("Error closing file: %s\n", file);
> > > + X509_free(cert);
> > > + return NULL;
> > > + } else if (!cert) {
> > > + HIP_ERROR("Could not decode certificate from file.\n");
> > > + return NULL;
> > > + }
> > > +
> > > + return cert;
> > > +}
> >
> > If I read this correctly, fp will not get closed on encountering an
> > invalid encoding format.
>
> Is my assessment correct?
It is correct, function logic fixed on branch.
> > > +/**
> > > + * Search for hip_cert parameter in @ msg and try to decode the data in
> > > + * the first certificate parameter of a X509 certificate.
> > > + *
> > > + * @param msg the message to extract the certificate from
> > > + *
> > > + * @return the first X509 certificate found in the message on success,
> > > + * NULL on error and if no certificates were found
> > > + */
> > > +X509 *cert_get_
> > > +{
> > > + const struct hip_cert *param_cert = NULL;
> > > +
> > > + ...
Christof Mroz (christof-mroz) wrote : Posted in a previous version of this proposal | # |
On 13.03.2012 17:31, Diego Biurrun wrote:
> On Mon, Mar 12, 2012 at 09:29:29PM +0100, Diego Biurrun wrote:
>> On Thu, Mar 08, 2012 at 06:41:47PM +0100, Diego Biurrun wrote:
>>> What is "param_cert + 1" supposed to be? Are you trying to move the
>>> pointer past the struct? This is extremely brittle, see the cast
>>> and the length calculation that are necessary.
>>
>> I'm still mystified about this one.
>
> Christoph confirms the intention. Repairing this likely entails quite
> a bit of fiddling with structures.
Related:
https:/
>>>> + if (optc == 2&& is_pos_
>>>
>>> OK, what exactly is the problem here? Why do you need the utility function?
>>
>> Can the original author shed some light on this?
>
> Christoph said scanf did not work for him. I guess we'll trust his word.
I still consider explicit type checks an anti pattern which should be
replaced by coercion, in this case scanf(), whenever easily possible.
As a fan of obscure facts I'd really like to know why scanf("%u",...)
failed. Don't let my curiosity stall the merge, though.
- 6125. By Diego Biurrun
-
Fix memory leaks in cert_match_
public_ key() and cert_verify_ chain() . - 6126. By Diego Biurrun
-
Fix a number of memory leaks in the certificate unit test.
- 6127. By Christoph Viethen
-
Fix a few more problems related to certificate generation:
Remove some redundancy from hipd/cert.c, and replace braces which served
to limit the scope of temporary variables.Fix serious bug in lib/core/
builder. c:build_ param_cert_ x509, which caused
corrupt certificate length value to be transmitted on little-endian
platforms. Also add the zeroing of the entire packet (again), to ease
debugging. Additionally, re-add the check for sufficient target space
before performing memcpy().Fix function cert_match_
public_ key(), enabling it to cope with OpenSSL's
"creative" error handling and return codes (verified against OpenSSL
0.9.8 source code). - 6128. By Diego Biurrun
-
Merge current trunk.
- 6129. By Diego Biurrun
-
Fix program logic in cert_load_
x509_certificat e(). The function would not correctly close file descriptors on error.
- 6130. By Diego Biurrun
-
Fix another memleak in the test_cert_
DER_encoding( ) unit test. - 6131. By René Hummen
-
add missing type in cert enum
This fixes an issue where the hipd would send certificates with the
type RESERVED (0) by default, instead of the correct type. - 6132. By René Hummen
-
merge trunk revision 6332
- 6133. By Christoph Viethen
-
Fix defective logic in conf_handle_
certificate( ). Still an awfully long function, though.
- 6134. By Christoph Viethen
-
Refactor conf_handle_
certificate( ), moving the functionality that evaluates
the input parameters and converts them into HIP message parameters into a
separate function conf_handle_certificate_ parms() . Also, overhaul the comments: Make sure they line-break before 80 chars,
clarify / shorten some of them, and add Doxygen headers. - 6135. By Christoph Viethen
-
Fix minor off-by-one bug in lib/core/
builder. c:build_ param_cert_ x509(). Also, replace one occurence of "struct in6_addr" by "hip_hit_t". Finally,
fix a little typo in a comment. - 6136. By Christoph Viethen
-
Correct type of the "der_len" element of the hip_cert_x509_resp structure
(see lib/core/protodefs. h) to be uint32_t. This structure reflects the
format of HIP messages on the wire, so the typical rules (use network
byte order, define sizes of struct elements unambiguously ... ) apply.This change causes a number of other changes in places where the very
same value gets handled. Note also that htonl() and ntohl() already were
used in a few of these places for byte order conversion of said value;
they generally use uint32_t for their input and output, so using
different types instead was just asking for trouble.
Unmerged revisions
Preview Diff
1 | === modified file 'Makefile.am' |
2 | --- Makefile.am 2012-03-09 14:42:31 +0000 |
3 | +++ Makefile.am 2012-03-09 15:19:21 +0000 |
4 | @@ -31,10 +31,10 @@ |
5 | EXTRA_DIST += .vimrc process_modules.py version.h |
6 | EXTRA_DIST += debian doc patches packaging tools/bazaar tools/maintainer |
7 | EXTRA_DIST += $(wildcard modules/*/module_info.xml) |
8 | +EXTRA_DIST += $(wildcard $(addprefix $(srcdir)/test/lib/core/,*.pem)) |
9 | EXTRA_DIST += $(wildcard $(addprefix $(srcdir)/tools/,*.cfg *.pl *.sh *.xml)) |
10 | EXTRA_DIST += $(wildcard $(addprefix $(srcdir)/hipfw/,*.cfg)) |
11 | EXTRA_DIST += $(HIPL_HEADER_LIST) |
12 | -EXTRA_DIST += hipd/pisa.c hipfw/pisa.c hipfw/pisa_cert.c |
13 | |
14 | ### user programs ### |
15 | bin_PROGRAMS = test/auth_performance \ |
16 | @@ -122,6 +122,7 @@ |
17 | hipd/user_ipsec_sadb_api.c \ |
18 | modules/heartbeat/hipd/heartbeat.c \ |
19 | modules/heartbeat_update/hipd/hb_update.c \ |
20 | + modules/cert/hipd/cert.c \ |
21 | modules/update/hipd/update.c \ |
22 | modules/update/hipd/update_builder.c \ |
23 | modules/update/hipd/update_locator.c \ |
24 | @@ -139,6 +140,7 @@ |
25 | tools/nsupdate/nsupdate.conf |
26 | |
27 | hipfw_hipfw_sources = hipfw/cache.c \ |
28 | + hipfw/cert.c \ |
29 | hipfw/dlist.c \ |
30 | hipfw/esp_prot_api.c \ |
31 | hipfw/esp_prot_config.c \ |
32 | @@ -170,6 +172,7 @@ |
33 | |
34 | lib_core_libhipcore_la_SOURCES = lib/core/builder.c \ |
35 | lib/core/capability.c \ |
36 | + lib/core/cert.c \ |
37 | lib/core/certtools.c \ |
38 | lib/core/conf.c \ |
39 | lib/core/crypto.c \ |
40 | @@ -220,6 +223,7 @@ |
41 | $(hipfw_hipfw_sources) |
42 | |
43 | test_check_lib_core_SOURCES = test/check_lib_core.c \ |
44 | + test/lib/core/cert.c \ |
45 | test/lib/core/crypto.c \ |
46 | test/lib/core/hit.c \ |
47 | test/lib/core/hostid.c \ |
48 | |
49 | === modified file 'configure.ac' |
50 | --- configure.ac 2012-03-09 14:42:31 +0000 |
51 | +++ configure.ac 2012-03-09 15:19:21 +0000 |
52 | @@ -101,6 +101,8 @@ |
53 | AC_DEFINE_UNQUOTED(HIPL_LOCKDIR, "$(eval echo $lockdir)") |
54 | AH_TEMPLATE(HIPL_LOCKDIR, [default lock file location]) |
55 | |
56 | +AC_DEFINE_UNQUOTED(HIPL_SOURCEDIR, "$(eval echo $srcdir)") |
57 | +AH_TEMPLATE(HIPL_SOURCEDIR, [HIPL source directory location]) |
58 | # Make sure that pythondir does not contain ${prefix} or similar so that it |
59 | # can be substituted into our Python scripts. |
60 | AC_SUBST(pythondir, $(eval echo $pythondir)) |
61 | |
62 | === modified file 'doc/HOWTO.xml.in' |
63 | --- doc/HOWTO.xml.in 2012-01-25 10:44:48 +0000 |
64 | +++ doc/HOWTO.xml.in 2012-03-09 15:19:21 +0000 |
65 | @@ -2532,6 +2532,81 @@ |
66 | |
67 | </chapter> |
68 | |
69 | +<chapter id="ch_cert_exchange"> |
70 | + <title>Certificate Exchange</title> |
71 | + |
72 | + <section id="ch_cert_functionality"> |
73 | + <title>Provided functionality</title> |
74 | + <para>At the protocol level, HIPL implements the HIP_CERT parameter as |
75 | + defined in RFC 6253. Specifically, X509 certificates are supported, whereas |
76 | + no functionality is provided for SPKI certificates. HIP does not define |
77 | + the usage of certificates in the protocol exchange. In HIPL, we currently |
78 | + add certificates to the R2 in the BEX and the second update message U2 |
79 | + (e.g. during the mobility-triggered update exchange). The HIP firewall |
80 | + verifies the certificate in the R2 and U2 if configured accordingly. If your |
81 | + use case requires certificates to be included in different messages, changes |
82 | + in the source code will be necessary.</para> |
83 | + </section> |
84 | + |
85 | + <section id="ch_cert_usage"> |
86 | + <title>Setting up a network scenario with certificates</title> |
87 | + <para>For the following guide, we assume a setup consisting of three |
88 | + machines (A, B, and C), where B is situated on the forwarding path between |
89 | + A and C. A and C execute the hipd, while B executes the hipfw. The hipd |
90 | + automatically adds a certificate to R2s and U2s if a file called |
91 | + host-cert.der is located in @sysconfdir@. The hipfw checks for certificates |
92 | + if certificate-based rules exist in @sysconfdir@/hipfw.conf.</para> |
93 | + <para>To set up certificates, you have to perform the following steps:</para> |
94 | + <itemizedlist> |
95 | + <listitem><para>Generate a root certificate in PEM format (e.g. with |
96 | + OpenSSL).</para></listitem> |
97 | + <listitem><para>Copy the root certificate to @sysconfdir@/ca-root-cert.pem on |
98 | + B.</para></listitem> |
99 | + <listitem><para>Add a certificate-based rule to @sysconfdir@/hipfw.conf on B |
100 | + (e.g. 'FORWARD -cert @sysconfdir@/ca-root-cert.pem ACCEPT').</para> |
101 | + </listitem> |
102 | + <listitem><para>Generate a certificate in DER format for the HI used by C |
103 | + and place it at @sysconfdir@/host-cert.der on C.</para></listitem> |
104 | + <listitem><para>No changes are required for A if its role is restricted to |
105 | + an initiator. Otherwise, A requires the same setup as C.</para></listitem> |
106 | + </itemizedlist> |
107 | + <para>The setup of a certificate-based network scenario can be vastly |
108 | + simplified by using a fourth HIPL-enabled host D as the certificate |
109 | + authority. In this case, generate the root certificate on D by running: |
110 | + </para> |
111 | + <para><programlisting> |
112 | + openssl req -new -x509 -key @sysconfdir@/hip_host_rsa_key_pub -out ca-root-cert.pem |
113 | + </programlisting></para> |
114 | + <para>NOTE: Apart from the common name, all fields in the certificate can be |
115 | + empty. The common name must contain the HIT of D.</para> |
116 | + <para>Now, run a BEX between C and D. After the BEX has succeeded, run the |
117 | + following command on D as root in order to generate the certificate for C: |
118 | + </para> |
119 | + <para><programlisting> |
120 | + hipconf acquire certificate #HIT_OF_C# > host-cert.der |
121 | + </programlisting></para> |
122 | + <para>As the final step, copy the certificates to the places mentioned in |
123 | + the guide above.</para> |
124 | + </section> |
125 | + |
126 | + <section id="ch_cert_troubleshooting"> |
127 | + <title>Troubleshooting</title> |
128 | + <para>There are a couple of things that may go wrong in a certificate-based |
129 | + setup. The most common ones are listed below. Please, make sure to check |
130 | + the listed items before asking questions on the hipl-users mailing list.</para> |
131 | + <itemizedlist> |
132 | + <listitem><para>Ensure that the certificates have not yet expired (e.g. |
133 | + by checking the certificate lifetime with OpenSSL).</para></listitem> |
134 | + <listitem><para>Validate that the time is set correctly on all hosts. |
135 | + </para></listitem> |
136 | + <listitem><para>Verify the certificate chain consisting of |
137 | + root-ca-cert.pem and host-cert.der with an external tool (e.g. with |
138 | + OpenSSL).</para></listitem> |
139 | + </itemizedlist> |
140 | + </section> |
141 | + |
142 | +</chapter> <!-- ch_cert_exchange --> |
143 | + |
144 | <chapter id="ch_exp_extensions"> |
145 | <title>Other Experimental HIP Extensions</title> |
146 | |
147 | |
148 | === modified file 'hipd/cert.c' |
149 | --- hipd/cert.c 2012-03-01 14:06:24 +0000 |
150 | +++ hipd/cert.c 2012-03-09 15:19:21 +0000 |
151 | @@ -49,10 +49,13 @@ |
152 | #include "lib/core/common.h" |
153 | #include "lib/core/crypto.h" |
154 | #include "lib/core/debug.h" |
155 | +#include "lib/core/hit.h" |
156 | #include "lib/core/ife.h" |
157 | +#include "lib/core/prefix.h" |
158 | #include "lib/core/protodefs.h" |
159 | #include "lib/core/straddr.h" |
160 | #include "lib/core/gpl/pk.h" |
161 | +#include "hadb.h" |
162 | #include "hidb.h" |
163 | #include "cert.h" |
164 | |
165 | @@ -661,20 +664,19 @@ |
166 | */ |
167 | int hip_cert_x509v3_handle_request_to_sign(struct hip_common *msg) |
168 | { |
169 | - int err = 0, i = 0, nid = 0, ret = 0, secs = 0, algo = 0; |
170 | - CONF *conf; |
171 | + int err = 0, i = 0, ret = 0, secs = 0, algo = 0; |
172 | + CONF *conf = NULL; |
173 | CONF_VALUE *item; |
174 | STACK_OF(CONF_VALUE) *sec_general = NULL; |
175 | - STACK_OF(CONF_VALUE) *sec_name = NULL; |
176 | STACK_OF(CONF_VALUE) *sec_ext = NULL; |
177 | |
178 | - X509_REQ *req = NULL; |
179 | X509_NAME *issuer = NULL; |
180 | X509_NAME *subj = NULL; |
181 | X509_EXTENSION *ext = NULL; |
182 | STACK_OF(X509_EXTENSION) *extlist = NULL; |
183 | - X509_NAME_ENTRY *ent; |
184 | - EVP_PKEY *pkey; |
185 | + X509_NAME_ENTRY *ent = NULL; |
186 | + EVP_PKEY *pkey = NULL; |
187 | + EVP_PKEY *sig_key = NULL; |
188 | /** XX TODO THIS should come from a configuration file |
189 | * monotonically increasing counter */ |
190 | long serial = 0; |
191 | @@ -682,89 +684,108 @@ |
192 | X509 *cert; |
193 | X509V3_CTX ctx; |
194 | const struct hip_cert_x509_req *subject; |
195 | - char subject_hit[41]; |
196 | - char issuer_hit[41]; |
197 | - char ialtname[45]; |
198 | - char saltname[45]; |
199 | - struct in6_addr *issuer_hit_n; |
200 | - struct hip_host_id *host_id; |
201 | - RSA *rsa = NULL; |
202 | - DSA *dsa = NULL; |
203 | + char subject_hit[INET6_ADDRSTRLEN]; |
204 | + char issuer_hit[INET6_ADDRSTRLEN] = { 0 }; |
205 | + char ialtname[INET6_ADDRSTRLEN + 3]; |
206 | + char saltname[INET6_ADDRSTRLEN + 3]; |
207 | + hip_hit_t *issuer_hit_n = NULL; |
208 | + struct hip_host_id *host_id = NULL; |
209 | + void *key = NULL; |
210 | unsigned char *der_cert = NULL; |
211 | int der_cert_len = 0; |
212 | char arg1[21]; |
213 | char arg2[21]; |
214 | - |
215 | - HIP_IFEL(!(issuer_hit_n = malloc(sizeof(struct in6_addr))), -1, |
216 | + const struct hip_tlv_common *validity_param = NULL; |
217 | + time_t expiry_time = 0; |
218 | + const struct hip_hadb_state *ha = NULL; |
219 | + |
220 | + |
221 | + HIP_IFEL(!(issuer_hit_n = malloc(sizeof(hip_hit_t))), -1, |
222 | "Malloc for subject failed\n"); |
223 | - HIP_IFEL(!(pkey = malloc(sizeof(EVP_PKEY))), -1, |
224 | - "Malloc for pkey failed\n"); |
225 | + HIP_IFEL(!(pkey = EVP_PKEY_new()), -1, |
226 | + "Allocating subject pub key failed\n"); |
227 | + HIP_IFEL(!(sig_key = EVP_PKEY_new()), -1, |
228 | + "Allocating issuer signature key failed\n"); |
229 | |
230 | - OpenSSL_add_all_algorithms(); |
231 | ERR_load_crypto_strings(); |
232 | |
233 | HIP_DEBUG("Reading configuration file (%s)\n", HIP_CERT_CONF_PATH); |
234 | conf = hip_open_conf(HIP_CERT_CONF_PATH); |
235 | sec_general = hip_read_conf_section("hip_x509v3", conf); |
236 | - sec_name = hip_read_conf_section("hip_x509v3_name", conf); |
237 | sec_ext = hip_read_conf_section("hip_x509v3_extensions", conf); |
238 | - NCONF_free(conf); |
239 | |
240 | - /* Get the general information */ |
241 | + /* Fail if the hip_x509v3 or hip_x509v3_name sections are not found. */ |
242 | HIP_IFEL(sec_general == NULL, -1, |
243 | "Failed to load general certificate information\n"); |
244 | - HIP_IFEL(!(req = X509_REQ_new()), -1, "Failed to create X509_REQ object"); |
245 | - |
246 | - HIP_IFEL(sec_name == NULL, -1, |
247 | - "Failed to load issuer naming information for the certificate\n"); |
248 | |
249 | /* Issuer naming */ |
250 | - if (sec_general != NULL) { |
251 | - /* Loop through the conf stack for general information */ |
252 | - extlist = sk_X509_EXTENSION_new_null(); |
253 | - for (i = 0; i < sk_CONF_VALUE_num(sec_general); i++) { |
254 | - item = sk_CONF_VALUE_value(sec_general, i); |
255 | - if (!strcmp(item->name, "issuerhit")) { |
256 | - strcpy(issuer_hit, item->value); |
257 | - ret = inet_pton(AF_INET6, item->value, issuer_hit_n); |
258 | - HIP_IFEL(ret < 0 && errno == EAFNOSUPPORT, -1, |
259 | - "Failed to convert issuer HIT to hip_hit_t\n"); |
260 | - HIP_DEBUG_HIT("Issuer HIT", issuer_hit_n); |
261 | - HIP_IFEL(!inet_ntop(AF_INET6, issuer_hit_n, |
262 | - issuer_hit, sizeof(issuer_hit)), |
263 | - -1, "Failed to convert subject hit to " |
264 | - "presentation format\n"); |
265 | - } |
266 | - if (!strcmp(item->name, "days")) { |
267 | - secs = HIP_CERT_DAY * atoi(item->value); |
268 | - } |
269 | - } |
270 | - } |
271 | - HIP_IFEL(!(issuer = X509_NAME_new()), -1, "Failed to set create issuer name"); |
272 | - nid = OBJ_txt2nid("commonName"); |
273 | - HIP_IFEL(nid == NID_undef, -1, "NID text not defined\n"); |
274 | - HIP_IFEL(!(ent = X509_NAME_ENTRY_create_by_NID(NULL, nid, MBSTRING_ASC, |
275 | + /* Loop through the conf stack for general information */ |
276 | + for (i = 0; i < sk_CONF_VALUE_num(sec_general); i++) { |
277 | + item = sk_CONF_VALUE_value(sec_general, i); |
278 | + if (!strcmp(item->name, "issuerhit")) { |
279 | + ret = inet_pton(AF_INET6, item->value, issuer_hit_n); |
280 | + HIP_IFEL(ret != 1, -1, |
281 | + "Failed to convert issuer HIT to hip_hit_t\n"); |
282 | + HIP_DEBUG_HIT("Issuer HIT", issuer_hit_n); |
283 | + hip_convert_hit_to_str(issuer_hit_n, NULL, issuer_hit); |
284 | + } |
285 | + if (!strcmp(item->name, "days")) { |
286 | + secs = HIP_CERT_DAY * atoi(item->value); |
287 | + } |
288 | + } |
289 | + |
290 | + /* In case no issuerhit was in the config, just use our default HIT. */ |
291 | + if (issuer_hit[0] == 0) { |
292 | + HIP_IFEL(hip_get_default_hit(issuer_hit_n), -1, |
293 | + "Unable to determine default HIT\n"); |
294 | + hip_convert_hit_to_str(issuer_hit_n, NULL, issuer_hit); |
295 | + } |
296 | + |
297 | + HIP_IFEL(!(issuer = X509_NAME_new()), -1, "Failed to create issuer name"); |
298 | + |
299 | + HIP_IFEL(!(ent = X509_NAME_ENTRY_create_by_NID(NULL, NID_commonName, MBSTRING_ASC, |
300 | (unsigned char *) issuer_hit, -1)), -1, |
301 | "Failed to create name entry for issuer\n"); |
302 | HIP_IFEL(X509_NAME_add_entry(issuer, ent, -1, 0) != 1, -1, |
303 | "Failed to add entry to issuer name\n"); |
304 | |
305 | + X509_NAME_ENTRY_free(ent); /* "ent" var will be re-used */ |
306 | + ent = NULL; |
307 | + |
308 | /* Subject naming */ |
309 | /* Get the subject hit from msg */ |
310 | HIP_IFEL(!(subject = hip_get_param(msg, HIP_PARAM_CERT_X509_REQ)), |
311 | - -1, "No cert_info struct found\n"); |
312 | - HIP_IFEL(!inet_ntop(AF_INET6, &subject->addr, subject_hit, sizeof(subject_hit)), |
313 | - -1, "Failed to convert subject hit to presentation format\n"); |
314 | - HIP_IFEL(!(subj = X509_NAME_new()), -1, "Failed to set create subject name"); |
315 | - nid = OBJ_txt2nid("commonName"); |
316 | - HIP_IFEL(nid == NID_undef, -1, "NID text not defined\n"); |
317 | - HIP_IFEL(!(ent = X509_NAME_ENTRY_create_by_NID(NULL, nid, MBSTRING_ASC, |
318 | + -1, "No cert_x509_req struct found\n"); |
319 | + HIP_IFEL(!ipv6_addr_is_hit(&subject->addr), |
320 | + -1, "Address in certificate request is no HIT.\n"); |
321 | + HIP_DEBUG_HIT("Subject HIT", &subject->addr); |
322 | + hip_convert_hit_to_str(&subject->addr, NULL, subject_hit); |
323 | + |
324 | + HIP_IFEL(!(subj = X509_NAME_new()), -1, "Failed to create subject name"); |
325 | + |
326 | + HIP_IFEL(!(ent = X509_NAME_ENTRY_create_by_NID(NULL, NID_commonName, MBSTRING_ASC, |
327 | (unsigned char *) subject_hit, -1)), -1, |
328 | "Failed to create name entry for subject\n"); |
329 | HIP_IFEL(X509_NAME_add_entry(subj, ent, -1, 0) != 1, -1, |
330 | "Failed to add entry to subject name\n"); |
331 | - HIP_IFEL(X509_REQ_set_subject_name(req, subj) != 1, -1, |
332 | - "Failed to add subject name to certificate request\n"); |
333 | + |
334 | + /* Were we sent a timestamp which indicates a requested cert validity? */ |
335 | + validity_param = hip_get_param(msg, HIP_PARAM_UINT); |
336 | + |
337 | + if (validity_param) { |
338 | + const uint32_t *valid_until_n = hip_get_param_contents_direct(validity_param); |
339 | + const uint32_t valid_until_h = ntohl(*valid_until_n); |
340 | + |
341 | + /* If time_t is only 32 bits wide and signed, we cannot copy a value of |
342 | + * valid_until_h which has its MSB set since it would be misunderstood |
343 | + * as being negative; so only set the value if this is not the case. */ |
344 | + if (!(sizeof(time_t) == 4 && ((time_t) -1 < 0) && |
345 | + (0x80000000 & valid_until_h))) { |
346 | + expiry_time = valid_until_h; |
347 | + } else { |
348 | + HIP_OUT_ERR(-1, "Received invalid timestamp parameter.\n"); |
349 | + } |
350 | + } |
351 | |
352 | /* XX TODO add a check to skip subjectAltName and issuerAltName because they are |
353 | * already in use by with IP:<hit> stuff */ |
354 | @@ -778,8 +799,6 @@ |
355 | "Failed to create extension\n"); |
356 | sk_X509_EXTENSION_push(extlist, ext); |
357 | } |
358 | - HIP_IFEL(!X509_REQ_add_extensions(req, extlist), -1, |
359 | - "Failed to add extensions to the request\n"); |
360 | } |
361 | |
362 | /** NOW WE ARE READY TO CREATE A CERTIFICATE FROM THE REQUEST */ |
363 | @@ -797,33 +816,63 @@ |
364 | "Failed to set subject name of certificate\n"); |
365 | HIP_IFEL(X509_set_issuer_name(cert, issuer) != 1, -1, |
366 | "Failed to set issuer name of certificate\n"); |
367 | - HIP_IFEL(!X509_gmtime_adj(X509_get_notBefore(cert), 0), -1, |
368 | + |
369 | + X509_get_notBefore(cert)->type = V_ASN1_GENERALIZEDTIME; |
370 | + X509_get_notAfter(cert)->type = V_ASN1_GENERALIZEDTIME; |
371 | + |
372 | + const time_t now = time(NULL); |
373 | + time_t starttime = 0, endtime = 0; |
374 | + time_t *starttime_p = NULL, *endtime_p = NULL; |
375 | + |
376 | + if (expiry_time) { |
377 | + /* A specific expiry time is demanded by the caller. */ |
378 | + if (now < expiry_time) { |
379 | + /* Just set it up as wanted. */ |
380 | + starttime = now; |
381 | + endtime = expiry_time; |
382 | + } else { |
383 | + /* Just set the start time to one second before the expiry time. |
384 | + * This yields a - syntactically - valid certificate. It is not |
385 | + * our task to second-guess the motives for requesting an expiry |
386 | + * time from the past. */ |
387 | + if (expiry_time == 1) { |
388 | + expiry_time++; /* another pathological case */ |
389 | + } |
390 | + starttime = expiry_time - 1; |
391 | + endtime = expiry_time; |
392 | + } |
393 | + |
394 | + starttime_p = &starttime; |
395 | + endtime_p = &endtime; |
396 | + secs = 0; |
397 | + } else { |
398 | + starttime_p = NULL; |
399 | + endtime_p = NULL; |
400 | + if (secs <= 0) { |
401 | + secs = 10; /* and yet another one */ |
402 | + } |
403 | + } |
404 | + |
405 | + HIP_IFEL(!X509_time_adj(X509_get_notBefore(cert), 0, starttime_p), -1, |
406 | "Error setting beginning time of the certificate"); |
407 | - HIP_IFEL(!X509_gmtime_adj(X509_get_notAfter(cert), secs), -1, |
408 | + HIP_IFEL(!X509_time_adj(X509_get_notAfter(cert), secs, endtime_p), -1, |
409 | "Error setting ending time of the certificate"); |
410 | |
411 | - HIP_DEBUG("Getting the key\n"); |
412 | - |
413 | - HIP_IFEL(hip_get_host_id_and_priv_key(issuer_hit_n, |
414 | - HIP_ANY_ALGO, |
415 | - &host_id, |
416 | - (void *) &rsa), |
417 | - -1, "Private key not found\n"); |
418 | - |
419 | - algo = host_id->rdata.algorithm; |
420 | - if (algo == HIP_HI_DSA) { |
421 | - dsa = (DSA *) rsa; |
422 | - } |
423 | + /* Get the subject public key from HADB */ |
424 | + HIP_IFEL(!(ha = hip_hadb_find_byhits(issuer_hit_n, &subject->addr)), |
425 | + -1, "Could not retrieve host association for subject HIT\n"); |
426 | + |
427 | + algo = ha->peer_pub->rdata.algorithm; |
428 | |
429 | switch (algo) { |
430 | case HIP_HI_RSA: |
431 | - HIP_IFEL(!EVP_PKEY_assign_RSA(pkey, rsa), -1, |
432 | + HIP_IFEL(!EVP_PKEY_set1_RSA(pkey, ha->peer_pub_key), -1, |
433 | "Failed to convert RSA to EVP_PKEY\n"); |
434 | HIP_IFEL(X509_set_pubkey(cert, pkey) != 1, -1, |
435 | "Failed to set public key of the certificate\n"); |
436 | break; |
437 | case HIP_HI_DSA: |
438 | - HIP_IFEL(!EVP_PKEY_assign_DSA(pkey, dsa), -1, |
439 | + HIP_IFEL(!EVP_PKEY_set1_DSA(pkey, ha->peer_pub_key), -1, |
440 | "Failed to convert DSA to EVP_PKEY\n"); |
441 | HIP_IFEL(X509_set_pubkey(cert, pkey) != 1, -1, |
442 | "Failed to set public key of the certificate\n"); |
443 | @@ -926,7 +975,25 @@ |
444 | HIP_OUT_ERR(-1, "Unknown algorithm\n"); |
445 | } |
446 | |
447 | - HIP_IFEL(!X509_sign(cert, pkey, digest), -1, |
448 | + /* Get the issuer key for signing */ |
449 | + HIP_IFEL(hip_get_host_id_and_priv_key(issuer_hit_n, HIP_ANY_ALGO, |
450 | + &host_id, &key), |
451 | + -1, "Private key not found\n"); |
452 | + |
453 | + switch (host_id->rdata.algorithm) { |
454 | + case HIP_HI_RSA: |
455 | + HIP_IFEL(!EVP_PKEY_set1_RSA(sig_key, key), -1, |
456 | + "Failed to convert RSA to EVP_PKEY\n"); |
457 | + break; |
458 | + case HIP_HI_DSA: |
459 | + HIP_IFEL(!EVP_PKEY_set1_DSA(sig_key, key), -1, |
460 | + "Failed to convert DSA to EVP_PKEY\n"); |
461 | + break; |
462 | + default: |
463 | + HIP_OUT_ERR(-1, "Unknown algorithm\n"); |
464 | + } |
465 | + |
466 | + HIP_IFEL(!X509_sign(cert, sig_key, digest), -1, |
467 | "Failed to sign x509v3 certificate\n"); |
468 | |
469 | /** DER */ |
470 | @@ -943,8 +1010,15 @@ |
471 | |
472 | out_err: |
473 | free(host_id); |
474 | - X509_REQ_free(req); |
475 | sk_X509_EXTENSION_pop_free(extlist, X509_EXTENSION_free); |
476 | + X509_NAME_ENTRY_free(ent); |
477 | + X509_NAME_free(subj); |
478 | + X509_NAME_free(issuer); |
479 | + NCONF_free(conf); |
480 | + ERR_free_strings(); |
481 | + EVP_PKEY_free(pkey); |
482 | + EVP_PKEY_free(sig_key); |
483 | + free(issuer_hit_n); |
484 | return err; |
485 | } |
486 | |
487 | @@ -985,7 +1059,7 @@ |
488 | der_cert = (unsigned char *) &p->der; |
489 | |
490 | vessel = p->der; |
491 | - HIP_IFEL((cert = d2i_X509(NULL, &vessel, verify.der_len)) == NULL, -1, |
492 | + HIP_IFEL((cert = d2i_X509(NULL, &vessel, ntohl(verify.der_len))) == NULL, -1, |
493 | "Failed to convert cert from DER to internal format\n"); |
494 | /* |
495 | * HIP_IFEL(!X509_print_fp(stdout, cert), -1, |
496 | |
497 | === modified file 'hipd/input.c' |
498 | --- hipd/input.c 2012-03-09 13:38:34 +0000 |
499 | +++ hipd/input.c 2012-03-09 15:19:21 +0000 |
500 | @@ -73,7 +73,6 @@ |
501 | #include "netdev.h" |
502 | #include "opp_mode.h" |
503 | #include "output.h" |
504 | -#include "pisa.h" |
505 | #include "pkt_handling.h" |
506 | #include "registration.h" |
507 | #include "input.h" |
508 | |
509 | === modified file 'hipd/output.c' |
510 | --- hipd/output.c 2012-03-09 13:38:34 +0000 |
511 | +++ hipd/output.c 2012-03-09 15:19:21 +0000 |
512 | @@ -65,7 +65,6 @@ |
513 | #include "hiprelay.h" |
514 | #include "nat.h" |
515 | #include "netdev.h" |
516 | -#include "pisa.h" |
517 | #include "registration.h" |
518 | #include "output.h" |
519 | |
520 | |
521 | === renamed file 'hipfw/pisa.c' => 'hipfw/cert.c' |
522 | --- hipfw/pisa.c 2011-11-25 13:52:20 +0000 |
523 | +++ hipfw/cert.c 2012-03-09 15:19:21 +0000 |
524 | @@ -1,5 +1,5 @@ |
525 | /* |
526 | - * Copyright (c) 2010 Aalto University and RWTH Aachen University. |
527 | + * Copyright (c) 2010-2011 Aalto University and RWTH Aachen University. |
528 | * |
529 | * Permission is hereby granted, free of charge, to any person |
530 | * obtaining a copy of this software and associated documentation |
531 | @@ -25,551 +25,190 @@ |
532 | |
533 | /** |
534 | * @file |
535 | - * This file contains PISA specific functions for the firewall. The basic idea |
536 | - * is to modify the HIP messages and manage state for allowed connections to |
537 | - * allow or reject associated ESP traffic. |
538 | + * certifcate functionality for the firewall |
539 | * |
540 | - * @brief PISA functions for the firewall |
541 | + * @brief certificate functions for the firewall |
542 | */ |
543 | |
544 | #define _BSD_SOURCE |
545 | |
546 | +#include <limits.h> |
547 | #include <stdint.h> |
548 | #include <stdio.h> |
549 | #include <stdlib.h> |
550 | #include <string.h> |
551 | -#include <time.h> |
552 | -#include <arpa/inet.h> |
553 | #include <netinet/in.h> |
554 | #include <linux/netfilter.h> |
555 | -#include <openssl/hmac.h> |
556 | +#include <linux/netfilter_ipv6.h> |
557 | +#include <openssl/x509.h> |
558 | |
559 | -#include "config.h" |
560 | +#include "lib/core/common.h" |
561 | +#include "lib/core/ife.h" |
562 | #include "lib/core/builder.h" |
563 | -#include "lib/core/certtools.h" |
564 | -#include "lib/core/crypto.h" |
565 | +#include "lib/core/cert.h" |
566 | #include "lib/core/debug.h" |
567 | -#include "lib/core/ife.h" |
568 | -#include "lib/core/performance.h" |
569 | -#include "lib/core/prefix.h" |
570 | -#include "modules/midauth/hipd/midauth.h" |
571 | #include "conntrack.h" |
572 | #include "hipfw_defines.h" |
573 | -#include "midauth.h" |
574 | -#include "pisa_cert.h" |
575 | -#include "pisa.h" |
576 | - |
577 | - |
578 | -#define PISA_RANDOM_LEN 16 |
579 | -#define PISA_PUZZLE_SEED 0xDEADC0DE |
580 | -#define PISA_PUZZLE_OPAQUE_LEN (4 + HIP_AH_SHA_LEN) |
581 | - |
582 | -/* pisa_check_for_random_update is called at least every PISA_RANDOM_TTL |
583 | - * seconds. Worst case timer resolution depends on the timeout in the select |
584 | - * call */ |
585 | -#define PISA_RANDOM_TTL 2.0 |
586 | - |
587 | -static char pisa_random_data[2][PISA_RANDOM_LEN]; |
588 | -static struct in6_addr community_operator_hit; |
589 | - |
590 | -/* @todo make this configurable, issuer HIT */ |
591 | -#define CO_HIT "2001:001a:b1b0:0aad:0f92:15ca:280c:9430" |
592 | -#define CO_HIT_FILE HIPL_SYSCONFDIR "/co_hit" |
593 | - |
594 | -/** |
595 | - * Generate a new random number and shift the old one down. |
596 | - */ |
597 | -static void pisa_generate_random(void) |
598 | -{ |
599 | - void *p0, *p1; |
600 | - |
601 | - p0 = &pisa_random_data[0][0]; |
602 | - p1 = &pisa_random_data[1][0]; |
603 | - |
604 | - memcpy(p0, p1, PISA_RANDOM_LEN); |
605 | - get_random_bytes(p1, PISA_RANDOM_LEN); |
606 | -} |
607 | - |
608 | -/** |
609 | - * Reads out the HIT of the Community-Operator |
610 | - * from file CO_HIT_FILE |
611 | - * @param hit A pointer to the char where the HIT should be stored |
612 | - * @return 1-> success |
613 | - * @return 0-> error |
614 | - */ |
615 | -static int pisa_read_communit_operator_hit(char *hit) |
616 | -{ |
617 | - FILE *f; |
618 | - char *eofline; |
619 | - |
620 | - f = fopen(CO_HIT_FILE, "r"); |
621 | - |
622 | - if (f == NULL) { |
623 | +#include "rule_management.h" |
624 | +#include "cert.h" |
625 | + |
626 | +// runtime configuration |
627 | +static int use_cert = false; |
628 | + |
629 | +static STACK_OF(X509) *root_chain = NULL; |
630 | + |
631 | +/** |
632 | + * Init function for certificate functionality. |
633 | + * |
634 | + * Iterate the firewall rules and look for the cert option. If found, |
635 | + * certificates are used and the root certificate is preloaded to verify |
636 | + * certificates. If no such rule is found, certificates are deactivated. |
637 | + * |
638 | + * @return 0 on success, negative if an error occurred |
639 | + */ |
640 | +int cert_init(void) |
641 | +{ |
642 | + X509 *cert = NULL; |
643 | + struct rule *rule = NULL; |
644 | + struct dlist *list = NULL; |
645 | + |
646 | + if (!(list = get_rule_list(NF_IP6_FORWARD))) { |
647 | + use_cert = false; |
648 | + HIP_DEBUG("certificates deactivated\n"); |
649 | return 0; |
650 | } |
651 | |
652 | - if (fgets(hit, INET6_ADDRSTRLEN, f) != NULL) { |
653 | - eofline = strchr(hit, '\n'); |
654 | - if (eofline) { |
655 | - *eofline = '\0'; |
656 | - } |
657 | - } else { |
658 | - HIP_ERROR("Fgets failed"); |
659 | - } |
660 | - fclose(f); |
661 | - |
662 | - return 1; |
663 | -} |
664 | - |
665 | -void pisa_check_for_random_update(void) |
666 | -{ |
667 | - static time_t lastupdate = 0; |
668 | - time_t now; |
669 | - |
670 | - time(&now); |
671 | - if (difftime(now, lastupdate) > PISA_RANDOM_TTL) { |
672 | - pisa_generate_random(); |
673 | - lastupdate = now; |
674 | - } |
675 | -} |
676 | - |
677 | -/** |
678 | - * Appends HMAC/SHA1 to a block of data. |
679 | - * |
680 | - * @param hit1 first HIT |
681 | - * @param hit2 second HIT |
682 | - * @param rnd which random number to use, either 0 or 1 |
683 | - * @param data pointer to buffer for data and the HMAC |
684 | - * @param data_len length of data |
685 | - * @return 0 on success |
686 | - */ |
687 | -static int pisa_append_hmac(struct in6_addr *hit1, struct in6_addr *hit2, |
688 | - int rnd, void *data, int data_len) |
689 | -{ |
690 | - uint8_t key[32 + PISA_RANDOM_LEN]; |
691 | - int err = 0; |
692 | - unsigned int len = HIP_AH_SHA_LEN; |
693 | - |
694 | - /* sanity checks for arguments */ |
695 | - HIP_IFEL(data == NULL, -1, "No data given.\n"); |
696 | - HIP_IFEL(hit1 == NULL, -1, "No first HIT given.\n"); |
697 | - HIP_IFEL(hit2 == NULL, -1, "No second HIT given.\n"); |
698 | - HIP_IFEL(data_len < 1, -1, "Data has invalid length.\n"); |
699 | - HIP_IFEL(rnd != 0 && rnd != 1, -1, "Random ID is neither 0 nor 1.\n"); |
700 | - |
701 | - /* The key for HMAC/SHA1 consists of: |
702 | - * 16 bytes HIT1 |
703 | - * 16 bytes HIT2 |
704 | - * PISA_RANDOM_LEN bytes pisa_random_data |
705 | - */ |
706 | - |
707 | - ipv6_addr_copy((struct in6_addr *) (key + 0), hit1); |
708 | - ipv6_addr_copy((struct in6_addr *) (key + 16), hit2); |
709 | - memcpy(key + 32, &pisa_random_data[rnd][0], PISA_RANDOM_LEN); |
710 | - |
711 | - HMAC(EVP_sha1(), key, 32 + PISA_RANDOM_LEN, data, data_len, |
712 | - (uint8_t *) data + data_len, &len); |
713 | - |
714 | -out_err: |
715 | - return err; |
716 | -} |
717 | - |
718 | -/** |
719 | - * Insert a PISA puzzle into a packet. |
720 | - * |
721 | - * @param ctx context of the packet where the puzzle will be inserted |
722 | - * @return success (0) or failure |
723 | - */ |
724 | -static int pisa_insert_puzzle(struct hip_fw_context *ctx) |
725 | -{ |
726 | - uint8_t opaque[PISA_PUZZLE_OPAQUE_LEN]; |
727 | - |
728 | - struct hip_common *hip = ctx->transport_hdr.hip; |
729 | - int seed = PISA_PUZZLE_SEED; |
730 | - |
731 | - memcpy(&opaque, &seed, 4); |
732 | - |
733 | - /* here we switch order of initiator and receiver to obtain a |
734 | - * different SHA1 hash */ |
735 | - pisa_append_hmac(&hip->hitr, &hip->hits, 1, &opaque, 4); |
736 | - |
737 | - return midauth_add_challenge_request(ctx, 3, 4, opaque, PISA_PUZZLE_OPAQUE_LEN); |
738 | -} |
739 | - |
740 | -/** |
741 | - * Check the validity of a PISA challenge_response. |
742 | - * |
743 | - * @param ctx context of the packet with the puzzle to check |
744 | - * @return pointer to the puzzle we accepted or NULL at failure |
745 | - */ |
746 | -static struct hip_challenge_response *pisa_check_challenge_response(struct hip_fw_context *ctx) |
747 | -{ |
748 | - struct hip_challenge_response *response; |
749 | - struct hip_common *hip = ctx->transport_hdr.hip; |
750 | - uint8_t hash[2][PISA_PUZZLE_OPAQUE_LEN]; |
751 | - int seed = PISA_PUZZLE_SEED; |
752 | - |
753 | - memcpy(&hash[0][0], &seed, 4); |
754 | - memcpy(&hash[1][0], &seed, 4); |
755 | - |
756 | - pisa_append_hmac(&hip->hits, &hip->hitr, 0, &hash[0], 4); |
757 | - pisa_append_hmac(&hip->hits, &hip->hitr, 1, &hash[1], 4); |
758 | - |
759 | - response = hip_get_param_readwrite(hip, HIP_PARAM_CHALLENGE_RESPONSE); |
760 | - |
761 | - while (response) { |
762 | - /* loop over all HIP_PARAM_CHALLENGE_RESPONSE */ |
763 | - if (hip_get_param_type(response) != HIP_PARAM_CHALLENGE_RESPONSE) { |
764 | - break; |
765 | - } |
766 | - if ((!memcmp(response->opaque, &hash[1][0], PISA_PUZZLE_OPAQUE_LEN)) || |
767 | - (!memcmp(response->opaque, &hash[0][0], PISA_PUZZLE_OPAQUE_LEN))) { |
768 | - if (!midauth_verify_challenge_response(response, |
769 | - hip->hits, |
770 | - hip->hitr)) { |
771 | - return response; |
772 | + if (!(root_chain = sk_X509_new_null())) { |
773 | + HIP_ERROR("Memory allocation failure.\n"); |
774 | + return -ENOMEM; |
775 | + } |
776 | + |
777 | + /* Search for rules with cert option */ |
778 | + while (list) { |
779 | + rule = list->data; |
780 | + if (rule->cert) { |
781 | + HIP_DEBUG("allowed cert: %s\n", rule->cert->value); |
782 | + use_cert = true; |
783 | + if (!(cert = cert_load_x509_certificate(rule->cert->value, |
784 | + ENCODING_FORMAT_PEM))) { |
785 | + HIP_ERROR("Could not load certificate of community operator from file: %s \n", |
786 | + rule->cert->value); |
787 | + return -1; |
788 | } |
789 | - } |
790 | - |
791 | - response = (struct hip_challenge_response *) |
792 | - hip_get_next_param_readwrite(hip, |
793 | - (struct hip_tlv_common *) response); |
794 | - } |
795 | - |
796 | - return NULL; |
797 | -} |
798 | - |
799 | -/** |
800 | - * Check the certificate of the packet. |
801 | - * |
802 | - * @param ctx context of the packet with the certificate to check |
803 | - * @return success (0) or failure |
804 | - */ |
805 | -static int pisa_check_certificate(struct hip_fw_context *ctx) |
806 | -{ |
807 | - struct hip_common *hip = ctx->transport_hdr.hip; |
808 | - const struct hip_cert *cert; |
809 | - struct hip_cert_spki_info ci; |
810 | - struct pisa_cert pc; |
811 | - char *buf = NULL; |
812 | - int err = 0, len; |
813 | - time_t now = time(NULL); |
814 | - |
815 | - cert = hip_get_param(hip, HIP_PARAM_CERT); |
816 | - HIP_IFEL(cert == NULL, -1, "No certificate found.\n"); |
817 | - |
818 | - len = ntohs(cert->length); |
819 | - buf = calloc(1, len); |
820 | - memcpy(buf, cert + 1, len); |
821 | - |
822 | - HIP_IFEL(hip_cert_spki_char2certinfo(buf, &ci), -1, |
823 | - "Certificate could not be parsed.\n"); |
824 | - HIP_IFEL(hip_cert_spki_lib_verify(&ci), -1, |
825 | - "Certificate could not be verified.\n"); |
826 | - |
827 | - pisa_split_cert(ci.cert, &pc); |
828 | - |
829 | - /* Three conditions must be fulfilled for a certificate to be valid: |
830 | - * |
831 | - * - The current time on the middlebox must be in the before/after |
832 | - * interval |
833 | - * - The certificate must be issued by the community operator (i.e. |
834 | - * the CO HIT must be used by the issuer) |
835 | - * - The host sending the certificate must be the one mentioned in |
836 | - * the certificate |
837 | - */ |
838 | - HIP_IFEL(now < pc.not_before, -1, |
839 | - "Certificate is not valid yet.\n"); |
840 | - HIP_IFEL(now > pc.not_after, -1, |
841 | - "Certificate has expired.\n"); |
842 | - |
843 | - |
844 | - HIP_IFEL(ipv6_addr_cmp(&pc.hit_issuer, &community_operator_hit) != 0, |
845 | - -1, "Certificate not issued by the community operator.\n"); |
846 | - HIP_IFEL(ipv6_addr_cmp(&pc.hit_subject, &hip->hits) != 0, -1, |
847 | - "Certificate does not belong to subject.\n"); |
848 | - |
849 | - HIP_INFO("Certificate successfully verified.\n"); |
850 | - |
851 | -out_err: |
852 | - free(buf); |
853 | - return err; |
854 | -} |
855 | - |
856 | -/** |
857 | - * Accept a connection via PISA. Update firewall to allow data packets to |
858 | - * pass through. |
859 | - * |
860 | - * @param ctx context of the packet that belongs to that connection |
861 | - */ |
862 | -static void pisa_accept_connection(const struct hip_fw_context *ctx) |
863 | -{ |
864 | - struct hip_common *hip = ctx->transport_hdr.hip; |
865 | - struct tuple *t = get_tuple_by_hits(&hip->hits, &hip->hitr); |
866 | - |
867 | - if (t) { |
868 | - t->connection->pisa_state = PISA_STATE_ALLOW; |
869 | - HIP_INFO("PISA accepted the connection.\n"); |
870 | - hip_fw_manage_all_esp_tuples(t, true); |
871 | - } else { |
872 | - HIP_ERROR("Connection not found.\n"); |
873 | - } |
874 | -} |
875 | - |
876 | -/** |
877 | - * Remove a connection from the list of accepted connections based on the hits |
878 | - * of a packet. |
879 | - * |
880 | - * @param ctx context of the packet that contains HITs of the connection |
881 | - */ |
882 | -static void pisa_remove_connection(const struct hip_fw_context *ctx) |
883 | -{ |
884 | - struct hip_common *hip = ctx->transport_hdr.hip; |
885 | - struct tuple *t = get_tuple_by_hits(&hip->hits, &hip->hitr); |
886 | - |
887 | - if (t) { |
888 | - t->connection->pisa_state = PISA_STATE_DISALLOW; |
889 | - HIP_INFO("PISA removed the connection.\n"); |
890 | - hip_fw_manage_all_esp_tuples(t, false); |
891 | - } else { |
892 | - HIP_ERROR("Connection not found.\n"); |
893 | - } |
894 | -} |
895 | - |
896 | -/** |
897 | - * Reject a connection via PISA. Update firewall to allow no data packets |
898 | - * to pass through. |
899 | - * |
900 | - * @param ctx context of the packet that belongs to that connection |
901 | - */ |
902 | -static void pisa_reject_connection(const struct hip_fw_context *ctx) |
903 | -{ |
904 | - HIP_INFO("PISA rejected the connection.\n"); |
905 | - pisa_remove_connection(ctx); |
906 | -} |
907 | - |
908 | -/** |
909 | - * Dummy function, necessary only for performance measurements. |
910 | - * |
911 | - * @param ctx context of the packet containing the I1 |
912 | - * @return NF_ACCEPT verdict |
913 | - */ |
914 | -static int pisa_handler_i1(UNUSED struct hip_fw_context *ctx) |
915 | -{ |
916 | -#ifdef CONFIG_HIP_PERFORMANCE |
917 | - HIP_DEBUG("Start PERF_BASE, PERF_I1\n"); |
918 | - hip_perf_start_benchmark(perf_set, PERF_BASE); |
919 | - hip_perf_start_benchmark(perf_set, PERF_I1); |
920 | -#endif |
921 | - |
922 | -#ifdef CONFIG_HIP_PERFORMANCE |
923 | - HIP_DEBUG("Stop and write PERF_I1\n"); |
924 | - hip_perf_stop_benchmark(perf_set, PERF_I1); |
925 | - hip_perf_write_benchmark(perf_set, PERF_I1); |
926 | -#endif |
927 | - |
928 | - return NF_ACCEPT; |
929 | -} |
930 | - |
931 | -/** |
932 | - * Dummy function, necessary only for performance measurements. |
933 | - * |
934 | - * @param ctx context of the packet containing the R1 |
935 | - * @return NF_ACCEPT verdict |
936 | - */ |
937 | -static int pisa_handler_r1(UNUSED struct hip_fw_context *ctx) |
938 | -{ |
939 | -#ifdef CONFIG_HIP_PERFORMANCE |
940 | - HIP_DEBUG("Start PERF_R1\n"); |
941 | - hip_perf_start_benchmark(perf_set, PERF_R1); |
942 | -#endif |
943 | - |
944 | -#ifdef CONFIG_HIP_PERFORMANCE |
945 | - HIP_DEBUG("Stop and write PERF_R1\n"); |
946 | - hip_perf_stop_benchmark(perf_set, PERF_R1); |
947 | - hip_perf_write_benchmark(perf_set, PERF_R1); |
948 | -#endif |
949 | - |
950 | - return NF_ACCEPT; |
951 | -} |
952 | - |
953 | -/** |
954 | - * Insert a PISA puzzle into the I2 packet. |
955 | - * |
956 | - * @param ctx context of the packet to modify |
957 | - * @return NF_ACCEPT verdict |
958 | - */ |
959 | -static int pisa_handler_i2(struct hip_fw_context *ctx) |
960 | -{ |
961 | -#ifdef CONFIG_HIP_PERFORMANCE |
962 | - HIP_DEBUG("Start PERF_I2\n"); |
963 | - hip_perf_start_benchmark(perf_set, PERF_I2); |
964 | -#endif |
965 | - pisa_insert_puzzle(ctx); |
966 | - |
967 | -#ifdef CONFIG_HIP_PERFORMANCE |
968 | - HIP_DEBUG("Stop and write PERF_I2\n"); |
969 | - hip_perf_stop_benchmark(perf_set, PERF_I2); |
970 | - hip_perf_write_benchmark(perf_set, PERF_I2); |
971 | -#endif |
972 | - |
973 | - return NF_ACCEPT; |
974 | -} |
975 | - |
976 | -/** |
977 | - * Check for a PISA puzzle, a valid signature and a valid |
978 | - * certificate in the R2 packet. |
979 | - * |
980 | - * @param ctx context of the packet to check |
981 | - * @return verdict, either NF_ACCEPT or NF_DROP |
982 | - */ |
983 | -static int pisa_handler_r2(struct hip_fw_context *ctx) |
984 | -{ |
985 | - int verdict = NF_DROP, sig = 0, cert = 0; |
986 | - struct hip_challenge_response *solution = NULL; |
987 | - |
988 | -#ifdef CONFIG_HIP_PERFORMANCE |
989 | - HIP_DEBUG("Start PERF_R2\n"); |
990 | - hip_perf_start_benchmark(perf_set, PERF_R2); |
991 | -#endif |
992 | - |
993 | - solution = pisa_check_challenge_response(ctx); |
994 | - cert = pisa_check_certificate(ctx); |
995 | - |
996 | - if (solution == NULL || sig != 0 || cert != 0) { |
997 | - /* disallow further communication if either nonce, solution, |
998 | - * signature or certificate were not correct */ |
999 | - pisa_reject_connection(ctx); |
1000 | - verdict = NF_DROP; |
1001 | - } else { |
1002 | - /* allow futher communication otherwise */ |
1003 | - pisa_accept_connection(ctx); |
1004 | - verdict = NF_ACCEPT; |
1005 | - } |
1006 | - |
1007 | -#ifdef CONFIG_HIP_PERFORMANCE |
1008 | - HIP_DEBUG("Stop and write PERF_R2, PERF_BASE\n"); |
1009 | - hip_perf_stop_benchmark(perf_set, PERF_R2); |
1010 | - hip_perf_stop_benchmark(perf_set, PERF_BASE); |
1011 | - hip_perf_write_benchmark(perf_set, PERF_R2); |
1012 | - hip_perf_write_benchmark(perf_set, PERF_BASE); |
1013 | -#endif |
1014 | - |
1015 | - return verdict; |
1016 | -} |
1017 | - |
1018 | -/** |
1019 | - * Insert a PISA nonce and a PISA puzzle into the U1 packet. |
1020 | - * |
1021 | - * @param ctx context of the packet to modify |
1022 | - * @return NF_ACCEPT verdict |
1023 | - */ |
1024 | -static int pisa_handler_u1(struct hip_fw_context *ctx) |
1025 | -{ |
1026 | - pisa_insert_puzzle(ctx); |
1027 | - |
1028 | - return NF_ACCEPT; |
1029 | -} |
1030 | - |
1031 | -/** |
1032 | - * Check for a PISA nonce, a PISA puzzle, a valid signature and a valid |
1033 | - * certificate in the U2 packet. |
1034 | - * |
1035 | - * @param ctx context of the packet to check |
1036 | - * @return verdict, either NF_ACCEPT or NF_DROP |
1037 | - */ |
1038 | -static int pisa_handler_u2(struct hip_fw_context *ctx) |
1039 | -{ |
1040 | - int verdict = NF_DROP; |
1041 | - int sig = 0; |
1042 | - int cert = 0; |
1043 | - struct hip_challenge_response *solution = NULL; |
1044 | - |
1045 | - solution = pisa_check_challenge_response(ctx); |
1046 | - cert = pisa_check_certificate(ctx); |
1047 | - |
1048 | - if (solution == NULL || sig != 0 || cert != 0) { |
1049 | - HIP_DEBUG("U2 packet did not match criteria: " |
1050 | - "solution %p, signature %i, cert %i\n", |
1051 | - solution, sig, cert); |
1052 | - verdict = NF_DROP; |
1053 | - } else { |
1054 | - /* packet was ok, insert another puzzle */ |
1055 | - pisa_insert_puzzle(ctx); |
1056 | - verdict = NF_ACCEPT; |
1057 | - } |
1058 | - |
1059 | - return verdict; |
1060 | -} |
1061 | - |
1062 | -/** |
1063 | - * Check for a PISA nonce and a valid signature in the U3 packet. |
1064 | - * |
1065 | - * @param ctx context of the packet to check |
1066 | - * @return verdict, either NF_ACCEPT or NF_DROP |
1067 | - */ |
1068 | -static int pisa_handler_u3(struct hip_fw_context *ctx) |
1069 | -{ |
1070 | - int verdict = NF_DROP; |
1071 | - int sig = 0; |
1072 | - struct hip_challenge_response *solution = NULL; |
1073 | - |
1074 | - solution = pisa_check_challenge_response(ctx); |
1075 | - |
1076 | - if (solution == NULL || sig != 0) { |
1077 | - HIP_DEBUG("U2 packet did not match criteria: " |
1078 | - "solution %p\n", |
1079 | - solution); |
1080 | - pisa_reject_connection(ctx); |
1081 | - verdict = NF_DROP; |
1082 | - } else { |
1083 | - pisa_accept_connection(ctx); |
1084 | - verdict = NF_ACCEPT; |
1085 | - } |
1086 | - return verdict; |
1087 | -} |
1088 | - |
1089 | -/** |
1090 | - * Handle CLOSE_ACK packet. Remove the connection from the list of accepted |
1091 | - * connections |
1092 | - * |
1093 | - * @param ctx context of the packet |
1094 | - * @return verdict, either NF_ACCEPT or NF_DROP |
1095 | - */ |
1096 | -static int pisa_handler_close_ack(struct hip_fw_context *ctx) |
1097 | -{ |
1098 | - pisa_remove_connection(ctx); |
1099 | - return NF_ACCEPT; |
1100 | -} |
1101 | - |
1102 | -/** |
1103 | - * Initialize basic PISA functionality |
1104 | - * |
1105 | - * @param h function pointers for packet handlers |
1106 | - */ |
1107 | -void pisa_init(struct midauth_handlers *h) |
1108 | -{ |
1109 | - char hit[INET6_ADDRSTRLEN]; |
1110 | - h->i1 = pisa_handler_i1; |
1111 | - h->r1 = pisa_handler_r1; |
1112 | - h->i2 = pisa_handler_i2; |
1113 | - h->r2 = pisa_handler_r2; |
1114 | - h->u1 = pisa_handler_u1; |
1115 | - h->u2 = pisa_handler_u2; |
1116 | - h->u3 = pisa_handler_u3; |
1117 | - h->close = midauth_handler_accept; |
1118 | - h->close_ack = pisa_handler_close_ack; |
1119 | - |
1120 | - pisa_generate_random(); |
1121 | - pisa_generate_random(); |
1122 | - |
1123 | - if (!pisa_read_communit_operator_hit(hit)) { |
1124 | - hit[0] = '\0'; |
1125 | - HIP_ERROR("Could not load Communit-Operator HIT from file %s\n", |
1126 | - CO_HIT_FILE); |
1127 | - } |
1128 | - |
1129 | - if (inet_pton(AF_INET6, hit, &community_operator_hit) <= 0) { |
1130 | - HIP_ERROR("Coult not parse Community-Operator HIT\n"); |
1131 | - } |
1132 | + sk_X509_push(root_chain, cert); |
1133 | + } |
1134 | + list = list->next; |
1135 | + } |
1136 | + |
1137 | + if (use_cert) { |
1138 | + HIP_DEBUG("certificates activated\n"); |
1139 | + } |
1140 | + |
1141 | + return 0; |
1142 | +} |
1143 | + |
1144 | +/** |
1145 | + * Uninit function for certificate functionality. |
1146 | + * |
1147 | + * @return 0 |
1148 | + */ |
1149 | +int cert_uninit(void) |
1150 | +{ |
1151 | + sk_X509_free(root_chain); |
1152 | + return 0; |
1153 | +} |
1154 | + |
1155 | +/** |
1156 | + * Helper function that converts the special RSA and DSA key structures |
1157 | + * to the generic EVP_PKEY structure. |
1158 | + * |
1159 | + * @param key the RSA or DSA key structure |
1160 | + * @param algo either HIP_HI_RSA or HIP_HI_DSA |
1161 | + * |
1162 | + * @return the EVP_PKEY structure that wraps the original key, |
1163 | + * or NULL on error |
1164 | + */ |
1165 | +static EVP_PKEY *any_key_to_evp_key(void *key, int algo) |
1166 | +{ |
1167 | + int err = 0; |
1168 | + EVP_PKEY *ret = NULL; |
1169 | + |
1170 | + if (!(ret = EVP_PKEY_new())) { |
1171 | + HIP_ERROR("Could not init EVP_PKEY wrapper\n"); |
1172 | + return NULL; |
1173 | + } |
1174 | + |
1175 | + switch (algo) { |
1176 | + case HIP_HI_RSA: |
1177 | + err = EVP_PKEY_assign_RSA(ret, key); |
1178 | + break; |
1179 | + case HIP_HI_DSA: |
1180 | + err = EVP_PKEY_assign_DSA(ret, key); |
1181 | + break; |
1182 | + default: |
1183 | + HIP_DEBUG("Unknown algorithm \n"); |
1184 | + } |
1185 | + if (err == 0) { |
1186 | + HIP_ERROR("Could not assign key to EVP_PKEY.\n"); |
1187 | + EVP_PKEY_free(ret); |
1188 | + return NULL; |
1189 | + } |
1190 | + |
1191 | + return ret; |
1192 | +} |
1193 | + |
1194 | +/** |
1195 | + * Extract the certificate from the R2 packet and match the contained public |
1196 | + * key against the HI provided in the R1 and try to build and verify |
1197 | + * a certificate chain. |
1198 | + * |
1199 | + * For an update exchange, a certificate must be contained either in the U2 |
1200 | + * (if the exchange was started by the Initiator) or in the U3 |
1201 | + * (if the exchange was started by the Responder). If a certificate cannot be |
1202 | + * found in these situations an error is returned. |
1203 | + * |
1204 | + * @param common the R2 or U2 packet |
1205 | + * @param tuple the connection tracking tuple |
1206 | + * @param ctx the firewall context |
1207 | + * @return 0 on success, negative error code otherwise |
1208 | + */ |
1209 | +int cert_handle_certificate(const struct hip_common *const common, |
1210 | + UNUSED struct tuple *const tuple, |
1211 | + UNUSED const struct hip_fw_context *const ctx) |
1212 | +{ |
1213 | + X509 *cert = NULL; |
1214 | + EVP_PKEY *pkey = NULL; |
1215 | + |
1216 | + if (use_cert) { |
1217 | + /* Should there be a certificate? |
1218 | + * Not if this update is not sent by the Responder. */ |
1219 | + if (!(tuple->direction == REPLY_DIR)) { |
1220 | + return 0; |
1221 | + } |
1222 | + |
1223 | + /* Extract certificate of trust point from the packet. */ |
1224 | + if (!(cert = cert_get_X509_from_msg(common))) { |
1225 | + HIP_DEBUG("Could not find trust-point certificate in R2/U2.\n"); |
1226 | + return -1; |
1227 | + } |
1228 | + |
1229 | + /* Match HI against public key in given certificate. */ |
1230 | + pkey = any_key_to_evp_key(tuple->hip_tuple->data->src_pub_key, |
1231 | + hip_get_host_id_algo(tuple->hip_tuple->data->src_hi)); |
1232 | + if (!cert_match_public_key(cert, pkey)) { |
1233 | + HIP_ERROR("HI does not match public key in given certificate.\n"); |
1234 | + return -1; |
1235 | + } |
1236 | + HIP_DEBUG("HI matches given certificate.\n"); |
1237 | + |
1238 | + /* Check certificate of trust point. */ |
1239 | + if (cert_verify_chain(cert, NULL, root_chain, NULL)) { |
1240 | + HIP_ERROR("Could not verify trust point certificate.\n"); |
1241 | + return -1; |
1242 | + } |
1243 | + |
1244 | + HIP_DEBUG("Verified trust-point certificate.\n"); |
1245 | + } |
1246 | + |
1247 | + return 0; |
1248 | } |
1249 | |
1250 | === renamed file 'hipfw/pisa.h' => 'hipfw/cert.h' |
1251 | --- hipfw/pisa.h 2011-11-25 13:52:20 +0000 |
1252 | +++ hipfw/cert.h 2012-03-09 15:19:21 +0000 |
1253 | @@ -1,5 +1,5 @@ |
1254 | /* |
1255 | - * Copyright (c) 2010 Aalto University and RWTH Aachen University. |
1256 | + * Copyright (c) 2010-2011 Aalto University and RWTH Aachen University. |
1257 | * |
1258 | * Permission is hereby granted, free of charge, to any person |
1259 | * obtaining a copy of this software and associated documentation |
1260 | @@ -23,26 +23,16 @@ |
1261 | * OTHER DEALINGS IN THE SOFTWARE. |
1262 | */ |
1263 | |
1264 | -#ifndef HIPL_HIPFW_PISA_H |
1265 | -#define HIPL_HIPFW_PISA_H |
1266 | - |
1267 | -#include "midauth.h" |
1268 | - |
1269 | -#define PISA_STATE_DISALLOW 0 |
1270 | -#define PISA_STATE_ALLOW 1 |
1271 | - |
1272 | -#ifdef CONFIG_HIP_PISA |
1273 | -/** |
1274 | - * Register PISA handlers with midauth and initialize data structures. |
1275 | - * |
1276 | - * @param h pointer to the handlers |
1277 | - */ |
1278 | -void pisa_init(struct midauth_handlers *h); |
1279 | -#endif |
1280 | - |
1281 | -/** |
1282 | - * Check if a new random number is necessary. |
1283 | - */ |
1284 | -void pisa_check_for_random_update(void); |
1285 | - |
1286 | -#endif /* HIPL_HIPFW_PISA_H */ |
1287 | +#ifndef HIPL_HIPFW_CERT_H |
1288 | +#define HIPL_HIPFW_CERT_H |
1289 | + |
1290 | +#include "hipfw_defines.h" |
1291 | + |
1292 | +int cert_init(void); |
1293 | +int cert_uninit(void); |
1294 | + |
1295 | +int cert_handle_certificate(const struct hip_common *const common, |
1296 | + struct tuple *const tuple, |
1297 | + const struct hip_fw_context *const ctx); |
1298 | + |
1299 | +#endif /* HIPL_HIPFW_CERT_H */ |
1300 | |
1301 | === modified file 'hipfw/conntrack.c' |
1302 | --- hipfw/conntrack.c 2012-03-08 14:33:33 +0000 |
1303 | +++ hipfw/conntrack.c 2012-03-09 15:19:21 +0000 |
1304 | @@ -1,5 +1,5 @@ |
1305 | /* |
1306 | - * Copyright (c) 2010-2011 Aalto University and RWTH Aachen University. |
1307 | + * Copyright (c) 2010-2012 Aalto University and RWTH Aachen University. |
1308 | * |
1309 | * Permission is hereby granted, free of charge, to any person |
1310 | * obtaining a copy of this software and associated documentation |
1311 | @@ -62,8 +62,9 @@ |
1312 | #include "lib/core/state.h" |
1313 | #include "lib/core/gpl/pk.h" |
1314 | #include "modules/update/hipd/update.h" |
1315 | +#include "config.h" |
1316 | +#include "cert.h" |
1317 | #include "common_types.h" |
1318 | -#include "config.h" |
1319 | #include "conntrack.h" |
1320 | #include "dlist.h" |
1321 | #include "hslist.h" |
1322 | @@ -72,7 +73,7 @@ |
1323 | #include "hipfw.h" |
1324 | #include "helpers.h" |
1325 | #include "hslist.h" |
1326 | -#include "pisa.h" |
1327 | +#include "midauth.h" |
1328 | #include "reinject.h" |
1329 | |
1330 | |
1331 | @@ -1296,6 +1297,11 @@ |
1332 | return 0; |
1333 | } |
1334 | |
1335 | + if (cert_handle_certificate(common, tuple, ctx)) { |
1336 | + HIP_ERROR("certificate error on R2\n"); |
1337 | + return 0; |
1338 | + } |
1339 | + |
1340 | /* check if the R2 contains ESP protection anchor and store state */ |
1341 | if (esp_prot_conntrack_R2_anchor(common, tuple)) { |
1342 | HIP_ERROR("failed to track esp protection extension state\n"); |
1343 | @@ -1330,7 +1336,7 @@ |
1344 | uint8_t locator_type; |
1345 | |
1346 | ptr = (const char *) (locator + 1); |
1347 | - while (ptr < ptr + hip_get_param_contents_len(locator)) { |
1348 | + while (ptr < ((const char *) (locator + 1)) + hip_get_param_contents_len(locator)) { |
1349 | locator_type = ((const struct hip_locator_type_0 *) ptr)->header.locator_type; |
1350 | if (locator_type == HIP_LOCATOR_LOCATOR_TYPE_IPV6) { |
1351 | esp_dest_addr = &((const struct hip_locator_type_0 *) ptr)->address; |
1352 | @@ -1368,11 +1374,6 @@ |
1353 | { |
1354 | int err = 1; |
1355 | |
1356 | - if (hip_get_param_total_len(locator) - sizeof(struct hip_locator) < sizeof(struct hip_locator_type_0)) { |
1357 | - HIP_ERROR("no locator param found\n"); |
1358 | - return 0; |
1359 | - } |
1360 | - |
1361 | if (esp_info && locator && seq) { |
1362 | HIP_DEBUG("esp_info, locator and seq\n"); |
1363 | |
1364 | @@ -1386,6 +1387,11 @@ |
1365 | esp_tuple->spi = ntohl(esp_info->new_spi); |
1366 | esp_tuple->spi_update_id = seq->update_id; |
1367 | |
1368 | + if (hip_get_param_total_len(locator) - sizeof(struct hip_locator) < sizeof(struct hip_locator_type_0)) { |
1369 | + HIP_ERROR("no locator param found\n"); |
1370 | + return 0; |
1371 | + } |
1372 | + |
1373 | HIP_IFEL(!update_esp_dest_addr(locator, seq, esp_tuple), |
1374 | 0, "error updateing ESP destination addresses\n"); |
1375 | } else if (esp_info && seq) { |
1376 | @@ -1597,6 +1603,11 @@ |
1377 | return 0; |
1378 | } |
1379 | |
1380 | + if (cert_handle_certificate(common, tuple, ctx)) { |
1381 | + HIP_ERROR("certificate error on U2\n"); |
1382 | + return 0; |
1383 | + } |
1384 | + |
1385 | if (handle_second_update(tuple, ctx, esp_info, seq)) { |
1386 | HIP_ERROR("unable to process second UPDATE message\n"); |
1387 | return 0; |
1388 | |
1389 | === modified file 'hipfw/hipfw.c' |
1390 | --- hipfw/hipfw.c 2012-03-08 12:28:00 +0000 |
1391 | +++ hipfw/hipfw.c 2012-03-09 15:19:21 +0000 |
1392 | @@ -78,6 +78,7 @@ |
1393 | #include "hipd/hipd.h" |
1394 | #include "config.h" |
1395 | #include "cache.h" |
1396 | +#include "cert.h" |
1397 | #include "common_types.h" |
1398 | #include "conntrack.h" |
1399 | #include "esp_prot_api.h" |
1400 | @@ -87,7 +88,6 @@ |
1401 | #include "helpers.h" |
1402 | #include "lsi.h" |
1403 | #include "midauth.h" |
1404 | -#include "pisa.h" |
1405 | #include "port_bindings.h" |
1406 | #include "reinject.h" |
1407 | #include "rewrite.h" |
1408 | @@ -481,6 +481,8 @@ |
1409 | |
1410 | midauth_init(); |
1411 | |
1412 | + HIP_IFEL(cert_init(), -1, "failed to load extension (cert)\n"); |
1413 | + |
1414 | // Initializing local port cache database |
1415 | hip_port_bindings_init(true); |
1416 | /* Initialize raw sockets for packet reinjection */ |
1417 | @@ -628,6 +630,8 @@ |
1418 | fw_uninit_lsi_support(); |
1419 | hip_fw_uninit_conntrack(); |
1420 | |
1421 | + cert_uninit(); |
1422 | + |
1423 | #ifdef CONFIG_HIP_PERFORMANCE |
1424 | /* Deallocate memory of perf_set after finishing all of tests */ |
1425 | hip_perf_destroy(perf_set); |
1426 | @@ -1876,12 +1880,6 @@ |
1427 | continue; |
1428 | } |
1429 | |
1430 | -#ifdef CONFIG_HIP_PISA |
1431 | - if (use_midauth) { |
1432 | - pisa_check_for_random_update(); |
1433 | - } |
1434 | -#endif |
1435 | - |
1436 | if (FD_ISSET(h4->fd, &read_fdset)) { |
1437 | HIP_DEBUG("received IPv4 packet from iptables queue\n"); |
1438 | err = fw_handle_packet(buf, h4, 4, &ctx); |
1439 | |
1440 | === modified file 'hipfw/hipfw.conf' |
1441 | --- hipfw/hipfw.conf 2011-12-15 13:25:00 +0000 |
1442 | +++ hipfw/hipfw.conf 2012-03-09 15:19:21 +0000 |
1443 | @@ -7,5 +7,6 @@ |
1444 | # -i [!] <incoming interface> |
1445 | # -o [!] <outgoing interface> |
1446 | # -state [!] <state> --verify_responder --accept_mobile --decrypt_contents |
1447 | +# -cert <root certificate>" |
1448 | # |
1449 | |
1450 | |
1451 | === modified file 'hipfw/hipfw_defines.h' |
1452 | --- hipfw/hipfw_defines.h 2012-02-17 18:01:18 +0000 |
1453 | +++ hipfw/hipfw_defines.h 2012-03-09 15:19:21 +0000 |
1454 | @@ -158,7 +158,6 @@ |
1455 | /* members needed for ESP protection extension */ |
1456 | int num_esp_prot_tfms; |
1457 | uint8_t esp_prot_tfms[MAX_NUM_TRANSFORMS]; |
1458 | - int pisa_state; |
1459 | }; |
1460 | |
1461 | #endif /* HIPL_HIPFW_FIREWALL_DEFINES_H */ |
1462 | |
1463 | === modified file 'hipfw/main.c' |
1464 | --- hipfw/main.c 2011-11-25 13:52:20 +0000 |
1465 | +++ hipfw/main.c 2012-03-09 15:19:21 +0000 |
1466 | @@ -37,14 +37,15 @@ |
1467 | |
1468 | #include <stdio.h> |
1469 | #include <stdlib.h> |
1470 | +#include <string.h> |
1471 | #include <unistd.h> |
1472 | #include <sys/types.h> |
1473 | |
1474 | #include "lib/core/filemanip.h" |
1475 | #include "lib/core/debug.h" |
1476 | #include "lib/core/util.h" |
1477 | +#include "conntrack.h" |
1478 | #include "hipfw.h" |
1479 | -#include "conntrack.h" |
1480 | #include "midauth.h" |
1481 | |
1482 | |
1483 | |
1484 | === removed file 'hipfw/pisa_cert.c' |
1485 | --- hipfw/pisa_cert.c 2011-08-15 14:11:56 +0000 |
1486 | +++ hipfw/pisa_cert.c 1970-01-01 00:00:00 +0000 |
1487 | @@ -1,205 +0,0 @@ |
1488 | -/* |
1489 | - * Copyright (c) 2010 Aalto University and RWTH Aachen University. |
1490 | - * |
1491 | - * Permission is hereby granted, free of charge, to any person |
1492 | - * obtaining a copy of this software and associated documentation |
1493 | - * files (the "Software"), to deal in the Software without |
1494 | - * restriction, including without limitation the rights to use, |
1495 | - * copy, modify, merge, publish, distribute, sublicense, and/or sell |
1496 | - * copies of the Software, and to permit persons to whom the |
1497 | - * Software is furnished to do so, subject to the following |
1498 | - * conditions: |
1499 | - * |
1500 | - * The above copyright notice and this permission notice shall be |
1501 | - * included in all copies or substantial portions of the Software. |
1502 | - * |
1503 | - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, |
1504 | - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES |
1505 | - * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND |
1506 | - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT |
1507 | - * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, |
1508 | - * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING |
1509 | - * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR |
1510 | - * OTHER DEALINGS IN THE SOFTWARE. |
1511 | - */ |
1512 | - |
1513 | -/** |
1514 | - * @file |
1515 | - * This file deals with the PISA specific handling of SPKI certificates. The |
1516 | - * certificate is parsed and split into small chunks. |
1517 | - * |
1518 | - * @brief PISA handling for SPKI certificates |
1519 | - */ |
1520 | - |
1521 | -#define _BSD_SOURCE |
1522 | - |
1523 | -#include <string.h> |
1524 | -#include <time.h> |
1525 | -#include <arpa/inet.h> |
1526 | -#include <netinet/in.h> |
1527 | -#include <sys/types.h> |
1528 | - |
1529 | -#include "pisa_cert.h" |
1530 | - |
1531 | - |
1532 | -/** |
1533 | - * Extract parts of a SPKI certificate. |
1534 | - * |
1535 | - * @param cert pointer to the certificate text or part of a certificate text |
1536 | - * @param name pointer to the pattern we are looking for |
1537 | - * @param r pointer to a buffer that the search result will be copied to |
1538 | - * @return 0 on success |
1539 | - */ |
1540 | -static char *pisa_cert_get_part(char *cert, const char *name, char *r) |
1541 | -{ |
1542 | - int level = 0, len = 0; |
1543 | - char *p = cert, *start = NULL; |
1544 | - |
1545 | - if (!r) { |
1546 | - return NULL; |
1547 | - } |
1548 | - |
1549 | - if (!cert) { |
1550 | - goto out_err; |
1551 | - } |
1552 | - |
1553 | - if (!name) { |
1554 | - goto out_err; |
1555 | - } |
1556 | - |
1557 | - len = strlen(name); |
1558 | - if (len == 0) { |
1559 | - goto out_err; |
1560 | - } |
1561 | - |
1562 | - while (*p) { |
1563 | - if (*p == '(') { |
1564 | - level++; |
1565 | - if (level == 2 && !strncmp(p + 1, name, len)) { |
1566 | - if (*(p + len + 1) == ' ') { |
1567 | - start = p++; |
1568 | - break; |
1569 | - } |
1570 | - } |
1571 | - } |
1572 | - if (*p == ')') { |
1573 | - level--; |
1574 | - } |
1575 | - if (level == 0) { |
1576 | - break; |
1577 | - } |
1578 | - p++; |
1579 | - } |
1580 | - |
1581 | - if (!start) { |
1582 | - goto out_err; |
1583 | - } |
1584 | - |
1585 | - len = 0; |
1586 | - |
1587 | - while (*p) { |
1588 | - if (*p == '(') { |
1589 | - level++; |
1590 | - } |
1591 | - if (*p == ')') { |
1592 | - level--; |
1593 | - if (level == 1) { |
1594 | - len = p - start + 1; |
1595 | - break; |
1596 | - } |
1597 | - } |
1598 | - if (level == 0) { |
1599 | - break; |
1600 | - } |
1601 | - p++; |
1602 | - } |
1603 | - |
1604 | - strncpy(r, start, len); |
1605 | - r[len] = '\0'; |
1606 | - |
1607 | - return r; |
1608 | - |
1609 | -out_err: |
1610 | - r[0] = '\0'; |
1611 | - return NULL; |
1612 | -} |
1613 | - |
1614 | -/** |
1615 | - * Get the content from a SPKI certificate part. |
1616 | - * |
1617 | - * @param cert pointer to the certificate text or part of a certificate text |
1618 | - * @param name pointer to the pattern we are looking for |
1619 | - * @param r pointer to a buffer that the search result will be copied to |
1620 | - * @return 0 on success |
1621 | - */ |
1622 | -static void pisa_cert_get_content(char *cert, const char *name, char *r) |
1623 | -{ |
1624 | - char *start = cert; |
1625 | - int len = 0; |
1626 | - |
1627 | - if (!r) { |
1628 | - return; |
1629 | - } |
1630 | - |
1631 | - if (!cert || !name || !*name == '(') { |
1632 | - goto out_err; |
1633 | - } |
1634 | - |
1635 | - if (strlen(name) + 3 > strlen(cert)) { |
1636 | - goto out_err; |
1637 | - } |
1638 | - |
1639 | - if (strncmp(name, cert + 1, strlen(name))) { |
1640 | - goto out_err; |
1641 | - } |
1642 | - start = cert + strlen(name) + 2; |
1643 | - |
1644 | - if (*start == '\0') { |
1645 | - goto out_err; |
1646 | - } |
1647 | - |
1648 | - len = strlen(start) - 1; |
1649 | - if (*(start + len) != ')') { |
1650 | - goto out_err; |
1651 | - } |
1652 | - strncpy(r, start, len); |
1653 | - |
1654 | -out_err: |
1655 | - r[len] = '\0'; |
1656 | -} |
1657 | - |
1658 | -/** |
1659 | - * Splits a certificate into semantic chunks and converts these to |
1660 | - * sensible binary representations. |
1661 | - * |
1662 | - * @param cert the original certificate |
1663 | - * @param pc internal representation of the certificate |
1664 | - */ |
1665 | -void pisa_split_cert(char *cert, struct pisa_cert *pc) |
1666 | -{ |
1667 | - struct tm t; |
1668 | - char buffer1[224], buffer2[224]; |
1669 | - struct in6_addr addr; |
1670 | - |
1671 | - pisa_cert_get_part(cert, "not-before", buffer1); |
1672 | - pisa_cert_get_content(buffer1, "not-before", buffer2); |
1673 | - strptime(buffer2, "\"%Y-%m-%d_%H:%M:%S\"", &t); |
1674 | - pc->not_before = mktime(&t); |
1675 | - |
1676 | - pisa_cert_get_part(cert, "not-after", buffer1); |
1677 | - pisa_cert_get_content(buffer1, "not-after", buffer2); |
1678 | - strptime(buffer2, "\"%Y-%m-%d_%H:%M:%S\"", &t); |
1679 | - pc->not_after = mktime(&t); |
1680 | - |
1681 | - pisa_cert_get_part(cert, "issuer", buffer1); |
1682 | - pisa_cert_get_part(buffer1, "hash hit", buffer2); |
1683 | - pisa_cert_get_content(buffer2, "hash hit", buffer1); |
1684 | - inet_pton(AF_INET6, buffer1, &addr); |
1685 | - memcpy(&pc->hit_issuer, &addr, sizeof(struct in6_addr)); |
1686 | - |
1687 | - pisa_cert_get_part(cert, "subject", buffer1); |
1688 | - pisa_cert_get_part(buffer1, "hash hit", buffer2); |
1689 | - pisa_cert_get_content(buffer2, "hash hit", buffer1); |
1690 | - inet_pton(AF_INET6, buffer1, &addr); |
1691 | - memcpy(&pc->hit_subject, &addr, sizeof(struct in6_addr)); |
1692 | -} |
1693 | |
1694 | === removed file 'hipfw/pisa_cert.h' |
1695 | --- hipfw/pisa_cert.h 2011-11-25 13:52:20 +0000 |
1696 | +++ hipfw/pisa_cert.h 1970-01-01 00:00:00 +0000 |
1697 | @@ -1,47 +0,0 @@ |
1698 | -/* |
1699 | - * Copyright (c) 2010 Aalto University and RWTH Aachen University. |
1700 | - * |
1701 | - * Permission is hereby granted, free of charge, to any person |
1702 | - * obtaining a copy of this software and associated documentation |
1703 | - * files (the "Software"), to deal in the Software without |
1704 | - * restriction, including without limitation the rights to use, |
1705 | - * copy, modify, merge, publish, distribute, sublicense, and/or sell |
1706 | - * copies of the Software, and to permit persons to whom the |
1707 | - * Software is furnished to do so, subject to the following |
1708 | - * conditions: |
1709 | - * |
1710 | - * The above copyright notice and this permission notice shall be |
1711 | - * included in all copies or substantial portions of the Software. |
1712 | - * |
1713 | - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, |
1714 | - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES |
1715 | - * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND |
1716 | - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT |
1717 | - * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, |
1718 | - * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING |
1719 | - * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR |
1720 | - * OTHER DEALINGS IN THE SOFTWARE. |
1721 | - */ |
1722 | - |
1723 | -#ifndef HIPL_HIPFW_PISA_CERT_H |
1724 | -#define HIPL_HIPFW_PISA_CERT_H |
1725 | - |
1726 | -#include <time.h> |
1727 | -#include <netinet/in.h> |
1728 | - |
1729 | -struct pisa_cert { |
1730 | - struct in6_addr hit_issuer; |
1731 | - struct in6_addr hit_subject; |
1732 | - time_t not_before; |
1733 | - time_t not_after; |
1734 | -}; |
1735 | - |
1736 | -/** |
1737 | - * Split the hip_cert_spki_info.cert part into small chunks |
1738 | - * |
1739 | - * @param cert the hip_cert_spki_info.cert part of the certificate |
1740 | - * @param pc datastructure that will contain the chunks |
1741 | - */ |
1742 | -void pisa_split_cert(char *cert, struct pisa_cert *pc); |
1743 | - |
1744 | -#endif /* HIPL_HIPFW_PISA_CERT_H */ |
1745 | |
1746 | === modified file 'hipfw/rule_management.c' |
1747 | --- hipfw/rule_management.c 2011-12-15 13:53:03 +0000 |
1748 | +++ hipfw/rule_management.c 2012-03-09 15:19:21 +0000 |
1749 | @@ -68,6 +68,7 @@ |
1750 | #define IN_IF_STR "-i" |
1751 | #define OUT_IF_STR "-o" |
1752 | #define STATE_STR "-state" |
1753 | +#define CERT_STR "-cert" |
1754 | #define SRC_HI_STR "--hi" |
1755 | #define VERIFY_RESPONDER_STR "--verify_responder" |
1756 | #define ACCEPT_MOBILE_STR "--accept_mobile" |
1757 | @@ -97,6 +98,7 @@ |
1758 | STATE_OPTION, |
1759 | IN_IF_OPTION, |
1760 | OUT_IF_OPTION, |
1761 | + CERT_OPTION, |
1762 | HOOK |
1763 | }; |
1764 | |
1765 | @@ -248,6 +250,7 @@ |
1766 | rule->state = NULL; |
1767 | rule->in_if = NULL; |
1768 | rule->out_if = NULL; |
1769 | + rule->cert = NULL; |
1770 | rule->hook = -1; |
1771 | rule->accept = -1; |
1772 | return rule; |
1773 | @@ -283,6 +286,7 @@ |
1774 | free(rule->state); |
1775 | free_string_option(rule->in_if); |
1776 | free_string_option(rule->out_if); |
1777 | + free_string_option(rule->cert); |
1778 | free(rule); |
1779 | } |
1780 | } |
1781 | @@ -682,6 +686,15 @@ |
1782 | return NULL; |
1783 | } |
1784 | option_found = STATE_OPTION; |
1785 | + } else if (!strcmp(token, CERT_STR)) { |
1786 | + /* option already defined */ |
1787 | + /* rule only applicable to forward hook */ |
1788 | + if (rule->cert != NULL || rule->hook != NF_IP6_FORWARD) { |
1789 | + HIP_DEBUG("error parsing rule: cert option \n"); |
1790 | + free_rule(rule); |
1791 | + return NULL; |
1792 | + } |
1793 | + option_found = CERT_OPTION; |
1794 | } else if (!strcmp(token, VERIFY_RESPONDER_STR)) { |
1795 | /* related state option must be defined */ |
1796 | if (rule->state == NULL) { |
1797 | @@ -794,6 +807,16 @@ |
1798 | return NULL; |
1799 | } |
1800 | option_found = NO_OPTION; |
1801 | + } else if (option_found == CERT_OPTION) { |
1802 | + rule->cert = malloc(sizeof(struct string_option)); |
1803 | + rule->cert->value = strdup(token); |
1804 | + rule->cert->boolean = 0; |
1805 | + if (rule->cert == NULL || rule->cert->value == NULL) { |
1806 | + HIP_DEBUG("error parsing rule: cert value \n"); |
1807 | + free_rule(rule); |
1808 | + return NULL; |
1809 | + } |
1810 | + option_found = NO_OPTION; |
1811 | } else if (option_found == IN_IF_OPTION) { |
1812 | rule->in_if = parse_if(token); |
1813 | if (rule->in_if == NULL) { |
1814 | |
1815 | === modified file 'hipfw/rule_management.h' |
1816 | --- hipfw/rule_management.h 2011-11-25 13:52:20 +0000 |
1817 | +++ hipfw/rule_management.h 2012-03-09 15:19:21 +0000 |
1818 | @@ -76,6 +76,7 @@ |
1819 | struct hip_host_id *src_hi; |
1820 | struct int_option *type; |
1821 | struct state_option *state; |
1822 | + struct string_option *cert; |
1823 | struct string_option *in_if; |
1824 | struct string_option *out_if; |
1825 | unsigned int hook; |
1826 | |
1827 | === modified file 'lib/core/builder.c' |
1828 | --- lib/core/builder.c 2012-03-08 13:39:18 +0000 |
1829 | +++ lib/core/builder.c 2012-03-09 15:19:21 +0000 |
1830 | @@ -1118,6 +1118,10 @@ |
1831 | case HIP_MSG_REINIT_FULLRELAY: return "HIP_MSG_REINIT_FULLRELAY"; |
1832 | case HIP_MSG_FIREWALL_START: return "HIP_MSG_FIREWALL_START"; |
1833 | case HIP_MSG_MANUAL_UPDATE_PACKET: return "HIP_MSG_MANUAL_UPDATE_PACKET"; |
1834 | + case HIP_MSG_CERT_SPKI_SIGN: return "HIP_MSG_CERT_SPKI_SIGN"; |
1835 | + case HIP_MSG_CERT_SPKI_VERIFY: return "HIP_MSG_CERT_SPKI_VERIFY"; |
1836 | + case HIP_MSG_CERT_X509V3_SIGN: return "HIP_MSG_CERT_X509V3_SIGN"; |
1837 | + case HIP_MSG_CERT_X509V3_VERIFY: return "HIP_MSG_CERT_X509V3_VERIFY"; |
1838 | default: |
1839 | return lmod_get_packet_identifier(msg_type); |
1840 | } |
1841 | @@ -1137,6 +1141,8 @@ |
1842 | switch (param_type) { |
1843 | case HIP_PARAM_ACK: return "HIP_PARAM_ACK"; |
1844 | case HIP_PARAM_CERT: return "HIP_PARAM_CERT"; |
1845 | + case HIP_PARAM_CERT_X509_REQ: return "HIP_PARAM_CERT_X509_REQ"; |
1846 | + case HIP_PARAM_CERT_X509_RESP: return "HIP_PARAM_CERT_X509_RESP"; |
1847 | case HIP_PARAM_DH_SHARED_KEY: return "HIP_PARAM_DH_SHARED_KEY"; |
1848 | case HIP_PARAM_DIFFIE_HELLMAN: return "HIP_PARAM_DIFFIE_HELLMAN"; |
1849 | case HIP_PARAM_DSA_SIGN_DATA: return "HIP_PARAM_DSA_SIGN_DATA"; |
1850 | @@ -3265,7 +3271,8 @@ |
1851 | * @return zero on success or negative on failure |
1852 | */ |
1853 | int hip_build_param_cert(struct hip_common *msg, uint8_t group, uint8_t count, |
1854 | - uint8_t id, uint8_t type, void *data, size_t size) |
1855 | + uint8_t id, enum hip_cert_type type, void *data, |
1856 | + size_t size) |
1857 | { |
1858 | struct hip_cert cert; |
1859 | |
1860 | @@ -3352,7 +3359,7 @@ |
1861 | } |
1862 | |
1863 | /** |
1864 | - * Build and append a X509 certiticate request parameter into a HIP control |
1865 | + * Build and append a X509 certificate request parameter into a HIP control |
1866 | * message (on-the-wire) |
1867 | * |
1868 | * @param msg a pointer to the message where the parameter will be |
1869 | @@ -3361,7 +3368,7 @@ |
1870 | * @return zero on success, or negative on failure |
1871 | * @see <a href="http://tools.ietf.org/html/draft-ietf-hip-cert">draft-ietf-hip-cert</a> |
1872 | */ |
1873 | -int hip_build_param_cert_x509_req(struct hip_common *msg, struct in6_addr *addr) |
1874 | +int hip_build_param_cert_x509_req(struct hip_common *msg, hip_hit_t *addr) |
1875 | { |
1876 | struct hip_cert_x509_req subj; |
1877 | |
1878 | @@ -3399,7 +3406,7 @@ |
1879 | * @return zero on success, or negative on failure |
1880 | * @see <a href="http://tools.ietf.org/html/draft-ietf-hip-cert">draft-ietf-hip-cert</a> |
1881 | */ |
1882 | -int hip_build_param_cert_x509_resp(struct hip_common *msg, char *der, int len) |
1883 | +int hip_build_param_cert_x509_resp(struct hip_common *msg, char *der, unsigned len) |
1884 | { |
1885 | return build_param_cert_x509(msg, der, len, HIP_PARAM_CERT_X509_RESP); |
1886 | } |
1887 | @@ -3415,7 +3422,7 @@ |
1888 | * @return zero on success, or negative on failure |
1889 | * @see <a href="http://tools.ietf.org/html/draft-ietf-hip-cert">draft-ietf-hip-cert</a> |
1890 | */ |
1891 | -int hip_build_param_cert_x509_ver(struct hip_common *msg, char *der, int len) |
1892 | +int hip_build_param_cert_x509_ver(struct hip_common *msg, char *der, unsigned len) |
1893 | { |
1894 | return build_param_cert_x509(msg, der, len, HIP_PARAM_CERT_X509_REQ); |
1895 | } |
1896 | |
1897 | === modified file 'lib/core/builder.h' |
1898 | --- lib/core/builder.h 2012-02-23 10:43:16 +0000 |
1899 | +++ lib/core/builder.h 2012-03-09 15:19:21 +0000 |
1900 | @@ -115,13 +115,9 @@ |
1901 | uint32_t, |
1902 | uint16_t, |
1903 | struct hip_crypto_key *); |
1904 | -int hip_build_param_cert(struct hip_common *, |
1905 | - uint8_t, |
1906 | - uint8_t, |
1907 | - uint8_t, |
1908 | - uint8_t, |
1909 | - void *, |
1910 | - size_t); |
1911 | +int hip_build_param_cert(struct hip_common *msg, uint8_t group, uint8_t count, |
1912 | + uint8_t id, enum hip_cert_type type, void *data, |
1913 | + size_t size); |
1914 | int hip_build_param_puzzle(struct hip_common *const msg, |
1915 | const uint8_t val_K, |
1916 | const uint8_t lifetime, |
1917 | @@ -159,8 +155,10 @@ |
1918 | int hip_build_param_cert_spki_info(struct hip_common *msg, |
1919 | struct hip_cert_spki_info *cert_info); |
1920 | int hip_build_param_cert_x509_req(struct hip_common *, struct in6_addr *); |
1921 | -int hip_build_param_cert_x509_resp(struct hip_common *, char *, int); |
1922 | -int hip_build_param_cert_x509_ver(struct hip_common *, char *, int); |
1923 | +int hip_build_param_cert_x509_resp(struct hip_common *msg, char *der, |
1924 | + unsigned len); |
1925 | +int hip_build_param_cert_x509_ver(struct hip_common *msg, char *der, |
1926 | + unsigned len); |
1927 | |
1928 | int hip_build_param_hit_to_ip_set(struct hip_common *, const char *); |
1929 | int hip_build_user_hdr(struct hip_common *, hip_hdr, hip_hdr_err); |
1930 | |
1931 | === added file 'lib/core/cert.c' |
1932 | --- lib/core/cert.c 1970-01-01 00:00:00 +0000 |
1933 | +++ lib/core/cert.c 2012-03-09 15:19:21 +0000 |
1934 | @@ -0,0 +1,286 @@ |
1935 | +/* |
1936 | + * Copyright (c) 2010-2012 Aalto University and RWTH Aachen University. |
1937 | + * |
1938 | + * Permission is hereby granted, free of charge, to any person |
1939 | + * obtaining a copy of this software and associated documentation |
1940 | + * files (the "Software"), to deal in the Software without |
1941 | + * restriction, including without limitation the rights to use, |
1942 | + * copy, modify, merge, publish, distribute, sublicense, and/or sell |
1943 | + * copies of the Software, and to permit persons to whom the |
1944 | + * Software is furnished to do so, subject to the following |
1945 | + * conditions: |
1946 | + * |
1947 | + * The above copyright notice and this permission notice shall be |
1948 | + * included in all copies or substantial portions of the Software. |
1949 | + * |
1950 | + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, |
1951 | + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES |
1952 | + * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND |
1953 | + * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT |
1954 | + * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, |
1955 | + * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING |
1956 | + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR |
1957 | + * OTHER DEALINGS IN THE SOFTWARE. |
1958 | + */ |
1959 | + |
1960 | +/** |
1961 | + * @file |
1962 | + * @brief functionality for handling X509 certificates |
1963 | + */ |
1964 | + |
1965 | +#include <errno.h> |
1966 | +#include <stdio.h> |
1967 | +#include <stdlib.h> |
1968 | +#include <string.h> |
1969 | +#include <unistd.h> |
1970 | +#include <openssl/x509.h> |
1971 | +#include <openssl/pem.h> |
1972 | + |
1973 | +#include "builder.h" |
1974 | +#include "debug.h" |
1975 | +#include "ife.h" |
1976 | +#include "common.h" |
1977 | +#include "cert.h" |
1978 | + |
1979 | +/** |
1980 | + * This function encodes the given certificate to its DER encoding for |
1981 | + * transmission over the wire. The encoded certificate is written to @p buf. |
1982 | + * |
1983 | + * @param cert the certificate to encode |
1984 | + * @param buf the output is written here |
1985 | + * |
1986 | + * @return the length of the encoded data |
1987 | + * |
1988 | + * @note: The encoded data is in binary form and may contain embedded zeroes. |
1989 | + * Functions such as strlen() will not return the correct length of the |
1990 | + * encoded structure. Therefore the length value returned by this |
1991 | + * function should always be used. |
1992 | + */ |
1993 | +int cert_X509_to_DER(X509 *const cert, unsigned char **buf) |
1994 | +{ |
1995 | + int len; |
1996 | + |
1997 | + if (!cert) { |
1998 | + HIP_ERROR("Cannot encode NULL-certificate\n"); |
1999 | + return -1; |
2000 | + } |
2001 | + if (!buf) { |
2002 | + HIP_ERROR("Cannot create output buffer at NULL-pointer.\n"); |
2003 | + return -1; |
2004 | + } |
2005 | + |
2006 | + *buf = NULL; |
2007 | + len = i2d_X509(cert, buf); |
2008 | + |
2009 | + if (len < 0) { |
2010 | + HIP_ERROR("Could not DER-encode the given certificate.\n"); |
2011 | + return -1; |
2012 | + } |
2013 | + return len; |
2014 | +} |
2015 | + |
2016 | +/** |
2017 | + * Function to decode a DER-encoded certificate to the internal OpenSSL X509 |
2018 | + * structure. |
2019 | + * |
2020 | + * @param buf the buffer from which the DER-encoded certificate is read |
2021 | + * @param len the length of the DER-encoded certificate |
2022 | + * (NOTE: strlen() and similar functions fail, since DER is |
2023 | + * basically binary data that can contain 0-bytes). |
2024 | + * |
2025 | + * @return the OpenSSL X509 structure corresponding the DER-encoded |
2026 | + * certificate, NULL if errors occured |
2027 | + */ |
2028 | +X509 *cert_DER_to_X509(const unsigned char *buf, const int len) |
2029 | +{ |
2030 | + if (!buf) { |
2031 | + HIP_ERROR("Cannot decode from NULL-buffer\n"); |
2032 | + return NULL; |
2033 | + } |
2034 | + if (len <= 0) { |
2035 | + HIP_ERROR("Cannot decode certificate of length <= 0\n"); |
2036 | + return NULL; |
2037 | + } |
2038 | + return d2i_X509(NULL, &buf, len); |
2039 | +} |
2040 | + |
2041 | +/** |
2042 | + * Load a X509 certificate from @p file. If @p file contains more |
2043 | + * than one certificate, the certificate at the top of the file is |
2044 | + * returned. |
2045 | + * |
2046 | + * @param file the file to load the certficate from |
2047 | + * @param fmt the input format of the certificate |
2048 | + * |
2049 | + * @return a pointer to an X.509 certificate on success, NULL on error |
2050 | + */ |
2051 | +X509 *cert_load_x509_certificate(const char *const file, |
2052 | + enum encoding_format fmt) |
2053 | +{ |
2054 | + FILE *fp = NULL; |
2055 | + X509 *cert = NULL; |
2056 | + |
2057 | + if (!file) { |
2058 | + HIP_ERROR("Cannot read certificate from NULL-filename.\n"); |
2059 | + return NULL; |
2060 | + } |
2061 | + |
2062 | + fp = fopen(file, "rb"); |
2063 | + if (!fp) { |
2064 | + HIP_ERROR("Could not open file for reading: %s\n", file); |
2065 | + return NULL; |
2066 | + } |
2067 | + |
2068 | + if (fmt == ENCODING_FORMAT_PEM) { |
2069 | + cert = PEM_read_X509(fp, NULL, NULL, NULL); |
2070 | + } else if (fmt == ENCODING_FORMAT_DER) { |
2071 | + cert = d2i_X509_fp(fp, NULL); |
2072 | + } else { |
2073 | + HIP_ERROR("Invalid encoding format %i \n", fmt); |
2074 | + return NULL; |
2075 | + } |
2076 | + |
2077 | + if (fclose(fp)) { |
2078 | + HIP_ERROR("Error closing file: %s\n", file); |
2079 | + X509_free(cert); |
2080 | + return NULL; |
2081 | + } else if (!cert) { |
2082 | + HIP_ERROR("Could not decode certificate from file.\n"); |
2083 | + return NULL; |
2084 | + } |
2085 | + |
2086 | + return cert; |
2087 | +} |
2088 | + |
2089 | +/** |
2090 | + * Search for hip_cert parameter in @p msg and try to decode the data in |
2091 | + * the first certificate parameter of a X509 certificate. |
2092 | + * |
2093 | + * @param msg the message to extract the certificate from |
2094 | + * |
2095 | + * @return the first X509 certificate found in the message on success, |
2096 | + * NULL on error and if no certificates were found |
2097 | + */ |
2098 | +X509 *cert_get_X509_from_msg(const struct hip_common *const msg) |
2099 | +{ |
2100 | + const struct hip_cert *param_cert = NULL; |
2101 | + |
2102 | + if (!(param_cert = hip_get_param(msg, HIP_PARAM_CERT))) { |
2103 | + HIP_ERROR("Message contains no certificate.\n"); |
2104 | + return NULL; |
2105 | + } |
2106 | + |
2107 | + /* The contents of the certificate begin after the header of the |
2108 | + * hip_cert parameter. */ |
2109 | + return cert_DER_to_X509((const unsigned char *) (param_cert + 1), |
2110 | + ntohs(param_cert->length) - |
2111 | + sizeof(struct hip_cert) + |
2112 | + sizeof(struct hip_tlv_common)); |
2113 | +} |
2114 | + |
2115 | +/** |
2116 | + * Compare a given public key @p pkey with the public key |
2117 | + * contained in @p cert. |
2118 | + * |
2119 | + * @param cert the X509 certificate |
2120 | + * @param pkey the public key to match |
2121 | + * |
2122 | + * @return 1 if match, 0 otherwise |
2123 | + */ |
2124 | +int cert_match_public_key(X509 *cert, const EVP_PKEY *pkey) |
2125 | +{ |
2126 | + EVP_PKEY *pkey2 = NULL; |
2127 | + |
2128 | + if (!cert || !pkey) { |
2129 | + return 0; |
2130 | + } |
2131 | + pkey2 = X509_get_pubkey(cert); |
2132 | + return EVP_PKEY_cmp(pkey2, pkey); |
2133 | +} |
2134 | + |
2135 | +/** |
2136 | + * Build and verify a certificate chain. |
2137 | + * |
2138 | + * @param leaf_cert the certificate to verify |
2139 | + * @param trusted_lookup_dir certificates in this directory are used as |
2140 | + * root certificates |
2141 | + * @param trusted_chain a certificate stack that can contain additional |
2142 | + * trusted certificates |
2143 | + * @param untrusted_chain a chain of untrusted certificates that can be |
2144 | + * used to build a complete certificate chain |
2145 | + * |
2146 | + * @return 0 if a certificate chain could be built and |
2147 | + * verified, a non-zero error code otherwise |
2148 | + */ |
2149 | +int cert_verify_chain(X509 *leaf_cert, |
2150 | + const char *trusted_lookup_dir, |
2151 | + STACK_OF(X509) *trusted_chain, |
2152 | + STACK_OF(X509) *untrusted_chain) |
2153 | +{ |
2154 | + int err = 0; |
2155 | + X509_LOOKUP *lookup = NULL; |
2156 | + X509_STORE *verify_ctx_store = NULL; |
2157 | + X509_STORE_CTX *verify_ctx = NULL; |
2158 | + |
2159 | + if (!leaf_cert) { |
2160 | + HIP_ERROR("Cannot verify NULL-certificate.\n"); |
2161 | + return -1; |
2162 | + } |
2163 | + |
2164 | + if (!trusted_lookup_dir && !trusted_chain) { |
2165 | + HIP_ERROR("Need trusted dir and trusted chain.\n"); |
2166 | + return -1; |
2167 | + } |
2168 | + |
2169 | + /* Build the verify context */ |
2170 | + if (!(verify_ctx_store = X509_STORE_new())) { |
2171 | + HIP_ERROR("Failed to init certificate store.\n"); |
2172 | + return -1; |
2173 | + } |
2174 | + if (!(lookup = X509_STORE_add_lookup(verify_ctx_store, X509_LOOKUP_hash_dir()))) { |
2175 | + HIP_ERROR("Failed to init lookup directory.\n"); |
2176 | + return -1; |
2177 | + } |
2178 | + if (trusted_lookup_dir) { |
2179 | + if (!X509_LOOKUP_add_dir(lookup, trusted_lookup_dir, |
2180 | + X509_FILETYPE_PEM)) { |
2181 | + HIP_ERROR("Failed to add directory %s to trusted lookup resources.\n", |
2182 | + trusted_lookup_dir); |
2183 | + return -1; |
2184 | + } |
2185 | + } else { |
2186 | + X509_LOOKUP_add_dir(lookup, NULL, X509_FILETYPE_DEFAULT); |
2187 | + } |
2188 | + |
2189 | + if (!(verify_ctx = X509_STORE_CTX_new())) { |
2190 | + HIP_ERROR("Failed to allocate new verify context.\n"); |
2191 | + return -ENOMEM; |
2192 | + } |
2193 | + if (!X509_STORE_CTX_init(verify_ctx, verify_ctx_store, leaf_cert, |
2194 | + untrusted_chain)) { |
2195 | + HIP_ERROR("Failed to setup verify context.\n"); |
2196 | + X509_STORE_CTX_free(verify_ctx); |
2197 | + return -1; |
2198 | + } |
2199 | + if (trusted_chain) { |
2200 | + X509_STORE_CTX_trusted_stack(verify_ctx, trusted_chain); |
2201 | + } |
2202 | + |
2203 | + /* Finally do the verification and output some info on error */ |
2204 | + OpenSSL_add_all_algorithms(); |
2205 | + err = X509_verify_cert(verify_ctx); |
2206 | + |
2207 | + if (err != 1) { |
2208 | + err = X509_STORE_CTX_get_error(verify_ctx); |
2209 | + HIP_DEBUG("X509 verify cert error: %d \n", err); |
2210 | + HIP_DEBUG("at depth: %d \n", X509_STORE_CTX_get_error_depth(verify_ctx)); |
2211 | + HIP_DEBUG("reason: %s\n", X509_verify_cert_error_string(err)); |
2212 | + HIP_DEBUG("certificate:\n"); |
2213 | + X509_print_fp(stderr, X509_STORE_CTX_get_current_cert(verify_ctx)); |
2214 | + } else { |
2215 | + err = 0; |
2216 | + } |
2217 | + |
2218 | + X509_STORE_CTX_free(verify_ctx); |
2219 | + return err; |
2220 | +} |
2221 | |
2222 | === added file 'lib/core/cert.h' |
2223 | --- lib/core/cert.h 1970-01-01 00:00:00 +0000 |
2224 | +++ lib/core/cert.h 2012-03-09 15:19:21 +0000 |
2225 | @@ -0,0 +1,51 @@ |
2226 | +/* |
2227 | + * Copyright (c) 2010-2011 Aalto University and RWTH Aachen University. |
2228 | + * |
2229 | + * Permission is hereby granted, free of charge, to any person |
2230 | + * obtaining a copy of this software and associated documentation |
2231 | + * files (the "Software"), to deal in the Software without |
2232 | + * restriction, including without limitation the rights to use, |
2233 | + * copy, modify, merge, publish, distribute, sublicense, and/or sell |
2234 | + * copies of the Software, and to permit persons to whom the |
2235 | + * Software is furnished to do so, subject to the following |
2236 | + * conditions: |
2237 | + * |
2238 | + * The above copyright notice and this permission notice shall be |
2239 | + * included in all copies or substantial portions of the Software. |
2240 | + * |
2241 | + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, |
2242 | + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES |
2243 | + * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND |
2244 | + * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT |
2245 | + * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, |
2246 | + * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING |
2247 | + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR |
2248 | + * OTHER DEALINGS IN THE SOFTWARE. |
2249 | + */ |
2250 | + |
2251 | +#ifndef HIPL_LIB_CORE_CERT_H |
2252 | +#define HIPL_LIB_CORE_CERT_H |
2253 | + |
2254 | +#include <openssl/x509.h> |
2255 | + |
2256 | +#include "lib/core/protodefs.h" |
2257 | + |
2258 | +enum encoding_format { |
2259 | + ENCODING_FORMAT_PEM, |
2260 | + ENCODING_FORMAT_DER |
2261 | +}; |
2262 | + |
2263 | +int cert_X509_to_DER(X509 *const cert, unsigned char **buf); |
2264 | +X509 *cert_DER_to_X509(const unsigned char *const buf, const int len); |
2265 | + |
2266 | +X509 *cert_load_x509_certificate(const char *const file, |
2267 | + enum encoding_format fmt); |
2268 | +X509 *cert_get_X509_from_msg(const struct hip_common *const msg); |
2269 | + |
2270 | +int cert_match_public_key(X509 *cert, const EVP_PKEY *pkey); |
2271 | +int cert_verify_chain(X509 *leaf_cert, |
2272 | + const char *trusted_lookup_dir, |
2273 | + STACK_OF(X509) *trusted_chain, |
2274 | + STACK_OF(X509) *untrusted_chain); |
2275 | + |
2276 | +#endif /* HIPL_LIB_CORE_CERT_H */ |
2277 | |
2278 | === modified file 'lib/core/certtools.c' |
2279 | --- lib/core/certtools.c 2012-01-14 15:29:47 +0000 |
2280 | +++ lib/core/certtools.c 2012-03-09 15:19:21 +0000 |
2281 | @@ -710,8 +710,8 @@ |
2282 | /* get the struct from the message sent back by the daemon */ |
2283 | HIP_IFEL(!(p = hip_get_param(msg, HIP_PARAM_CERT_X509_RESP)), -1, |
2284 | "No name x509 struct found\n"); |
2285 | - memcpy(certificate, p->der, p->der_len); |
2286 | - err = p->der_len; |
2287 | + memcpy(certificate, p->der, ntohl(p->der_len)); |
2288 | + err = ntohl(p->der_len); |
2289 | |
2290 | out_err: |
2291 | free(msg); |
2292 | @@ -797,18 +797,18 @@ |
2293 | } |
2294 | |
2295 | /** |
2296 | - * Load a configuration file from HIP_CERT_CONF_PATH. |
2297 | + * Load the indicated configuration file. |
2298 | * |
2299 | * @return CONF pointer if OK, NULL on error |
2300 | */ |
2301 | CONF *hip_open_conf(const char *filename) |
2302 | { |
2303 | - long err; |
2304 | CONF *conf; |
2305 | |
2306 | conf = NCONF_new(NCONF_default()); |
2307 | - if (!NCONF_load(conf, filename, &err)) { |
2308 | + if (!NCONF_load(conf, filename, NULL)) { |
2309 | HIP_ERROR("Error opening the configuration file"); |
2310 | + NCONF_free(conf); |
2311 | return NULL; |
2312 | } |
2313 | return conf; |
2314 | |
2315 | === modified file 'lib/core/conf.c' |
2316 | --- lib/core/conf.c 2012-01-13 16:25:15 +0000 |
2317 | +++ lib/core/conf.c 2012-03-09 15:19:21 +0000 |
2318 | @@ -1,5 +1,5 @@ |
2319 | /* |
2320 | - * Copyright (c) 2010-2011 Aalto University and RWTH Aachen University. |
2321 | + * Copyright (c) 2010-2012 Aalto University and RWTH Aachen University. |
2322 | * |
2323 | * Permission is hereby granted, free of charge, to any person |
2324 | * obtaining a copy of this software and associated documentation |
2325 | @@ -59,10 +59,12 @@ |
2326 | #include <sys/ioctl.h> |
2327 | #include <sys/socket.h> |
2328 | #include <sys/types.h> |
2329 | +#include <openssl/pem.h> |
2330 | |
2331 | -#include "common.h" |
2332 | #include "config.h" |
2333 | #include "builder.h" |
2334 | +#include "cert.h" |
2335 | +#include "common.h" |
2336 | #include "crypto.h" |
2337 | #include "debug.h" |
2338 | #include "hostid.h" |
2339 | @@ -126,7 +128,8 @@ |
2340 | /* unused, was ACTION_HANDOVER 39 */ |
2341 | #define ACTION_MANUAL_UPDATE 40 |
2342 | #define ACTION_BROADCAST 41 |
2343 | -#define ACTION_MAX 42 /* exclusive */ |
2344 | +#define ACTION_ACQUIRE 42 |
2345 | +#define ACTION_MAX 43 /* exclusive */ |
2346 | |
2347 | /** |
2348 | * TYPE_ constant list, as an index for each action_handler function. |
2349 | @@ -176,7 +179,8 @@ |
2350 | /* unused, was TYPE_HANDOVER 42 */ |
2351 | #define TYPE_MANUAL_UPDATE 43 |
2352 | #define TYPE_BROADCAST 44 |
2353 | -#define TYPE_MAX 45 /* exclusive */ |
2354 | +#define TYPE_CERTIFICATE 45 |
2355 | +#define TYPE_MAX 46 /* exclusive */ |
2356 | |
2357 | /* #define TYPE_RELAY 22 */ |
2358 | |
2359 | @@ -230,6 +234,7 @@ |
2360 | "shotgun on|off\n" |
2361 | "id-to-addr hit|lsi\n" |
2362 | "broadcast on|off\n" |
2363 | + "acquire certificate <hit> [valid-till_timestamp]\n" |
2364 | ; |
2365 | |
2366 | /** |
2367 | @@ -648,6 +653,8 @@ |
2368 | } |
2369 | } else if (!strcmp("broadcast", argv[2])) { |
2370 | ret = ACTION_BROADCAST; |
2371 | + } else if (!strcmp("acquire", argv[2])) { |
2372 | + ret = ACTION_ACQUIRE; |
2373 | } |
2374 | |
2375 | return ret; |
2376 | @@ -698,6 +705,7 @@ |
2377 | case ACTION_TRANSORDER: |
2378 | case ACTION_NAT_LOCAL_PORT: |
2379 | case ACTION_NAT_PEER_PORT: |
2380 | + case ACTION_ACQUIRE: |
2381 | count = 2; |
2382 | break; |
2383 | default: |
2384 | @@ -750,6 +758,8 @@ |
2385 | } else { |
2386 | ret = TYPE_NAT; |
2387 | } |
2388 | + } else if (!strcmp("certificate", text)) { |
2389 | + ret = TYPE_CERTIFICATE; |
2390 | } else if (strcmp("locator", argv[2]) == 0) { |
2391 | ret = TYPE_LOCATOR; |
2392 | } else if (!strcmp("debug", text)) { |
2393 | @@ -819,6 +829,7 @@ |
2394 | case ACTION_HIT_TO_IP: |
2395 | case ACTION_HIT_TO_IP_SET: |
2396 | case ACTION_BROADCAST: |
2397 | + case ACTION_ACQUIRE: |
2398 | type_arg = 3; |
2399 | break; |
2400 | case ACTION_MANUAL_UPDATE: |
2401 | @@ -2424,6 +2435,122 @@ |
2402 | } |
2403 | |
2404 | /** |
2405 | + * Utility function which compactly checks whether a string represents |
2406 | + * a positive natural number, since scanf() is too lenient. |
2407 | + * |
2408 | + * @param string NULL-terminated string to be checked |
2409 | + * |
2410 | + * @return 1 if the only characters in the string are digits, |
2411 | + * optionally with one leading '+' sign; 0 otherwise |
2412 | + */ |
2413 | +static int is_pos_natural_number(const char *string) |
2414 | +{ |
2415 | + if (string) { |
2416 | + size_t len; |
2417 | + |
2418 | + // allow one leading '+' |
2419 | + if (string[0] == '+') { |
2420 | + string++; |
2421 | + } |
2422 | + |
2423 | + if ((len = strlen(string)) > 0) { |
2424 | + for (size_t i = 0; i < len; i++) { |
2425 | + if (string[i] < '0' || string[i] > '9') { |
2426 | + return 0; |
2427 | + } |
2428 | + } |
2429 | + return 1; |
2430 | + } |
2431 | + } |
2432 | + return 0; |
2433 | +} |
2434 | + |
2435 | +static int conf_handle_certificate(struct hip_common *msg, |
2436 | + int action, |
2437 | + const char *opt[], |
2438 | + int optc, |
2439 | + UNUSED int send_only) |
2440 | +{ |
2441 | + hip_hit_t subject_hit; |
2442 | + uint32_t valid_until_h = 0, valid_until_n = 0; |
2443 | + int scanf_res = 0, err = 0; |
2444 | + X509 *cert = NULL; |
2445 | + const struct hip_cert_x509_resp *p = NULL; |
2446 | + |
2447 | + /* Convert the parameter strings input by the user into the |
2448 | + * appropriate binary formats for further processing. */ |
2449 | + const int pton_res = inet_pton(AF_INET6, opt[0], &subject_hit); |
2450 | + |
2451 | + if (optc == 2 && is_pos_natural_number(opt[1])) { |
2452 | + /* Need to use sscanf() here: strtol() won't do since we want the result |
2453 | + * of the conversion to fit into an uint32_t, whereas strtol() and |
2454 | + * relatives would write to a variable of platform-dependent size. */ |
2455 | + scanf_res = sscanf(opt[1], "%" SCNu32, &valid_until_h); |
2456 | + } |
2457 | + |
2458 | + /* The second parameter after "acquire certificate" is optional, so we |
2459 | + * accept optc == 1 as well as optc == 2 (the latter is implied if |
2460 | + * scanf_res is 1). */ |
2461 | + if (pton_res == 1 && action == ACTION_ACQUIRE && |
2462 | + (optc == 1 || scanf_res == 1)) { |
2463 | + HIP_DEBUG_HIT("Requesting certificate for subject", &subject_hit); |
2464 | + |
2465 | + if (hip_build_user_hdr(msg, HIP_MSG_CERT_X509V3_SIGN, 0)) { |
2466 | + HIP_ERROR("Failed to build user message header.\n"); |
2467 | + return -1; |
2468 | + } |
2469 | + |
2470 | + /* If the user provides a second parameter (following the HIT), it is |
2471 | + * meant to indicate the point in time when validity of the issued |
2472 | + * certificate ends; expressed in "number of seconds since the epoch"; |
2473 | + * we use a uint32_t for this, so we're creating a year-2106-problem |
2474 | + * here (be scared). */ |
2475 | + if (scanf_res == 1) { |
2476 | + valid_until_n = htonl(valid_until_h); |
2477 | + if (hip_build_param_contents(msg, &valid_until_n, |
2478 | + HIP_PARAM_UINT, sizeof(uint32_t))) { |
2479 | + HIP_ERROR("Failed to build validity parameter.\n"); |
2480 | + return -1; |
2481 | + } |
2482 | + } |
2483 | + |
2484 | + if (hip_build_param_cert_x509_req(msg, &subject_hit)) { |
2485 | + HIP_ERROR("Failed to build cert_x509_req parameter.\n"); |
2486 | + return -1; |
2487 | + } |
2488 | + } else { |
2489 | + err = -1; |
2490 | + HIP_ERROR("Invalid arguments.\n"); |
2491 | + } |
2492 | + |
2493 | + /* Send the message to the daemon. The daemon fills the message. */ |
2494 | + if (hip_send_recv_daemon_info(msg, send_only, 0)) { |
2495 | + return -ECOMM; |
2496 | + } |
2497 | + |
2498 | + /* Handle the answer */ |
2499 | + if (!(p = hip_get_param(msg, HIP_PARAM_CERT_X509_RESP))) { |
2500 | + HIP_ERROR("No name x509 struct found\n"); |
2501 | + return -1; |
2502 | + } |
2503 | + const uint32_t der_len_h = ntohl(p->der_len); |
2504 | + if (!(cert = cert_DER_to_X509(p->der, der_len_h))) { |
2505 | + HIP_ERROR("Could not get X509 certificate from DER encoding\n."); |
2506 | + return -1; |
2507 | + } |
2508 | + if (fwrite(p->der, der_len_h, 1, stdout) != 1) { |
2509 | + HIP_ERROR("Couldn't output certificate.\n"); |
2510 | + return -1; |
2511 | + } |
2512 | + |
2513 | + /* Clear the msg (and in particular its message type field) |
2514 | + * to prevent hip_do_hipconf() from sending it again. */ |
2515 | + hip_msg_init(msg); |
2516 | + |
2517 | + return err; |
2518 | +} |
2519 | + |
2520 | +/** |
2521 | * Function pointer array containing pointers to handler functions. |
2522 | * Add a handler function for your new action in the action_handler[] array. |
2523 | * If you added a handler function here, do not forget to define that function |
2524 | @@ -2492,6 +2619,7 @@ |
2525 | NULL, /* 42: unused, was TYPE_HANDOVER */ |
2526 | conf_handle_manual_update, /* 43: TYPE_MANUAL_UPDATE */ |
2527 | conf_handle_broadcast, /* 44: TYPE_BROADCAST */ |
2528 | + conf_handle_certificate, /* 45: TYPE_CERTIFICATE */ |
2529 | NULL /* TYPE_MAX, the end. */ |
2530 | }; |
2531 | |
2532 | |
2533 | === modified file 'lib/core/protodefs.h' |
2534 | --- lib/core/protodefs.h 2012-03-08 18:50:52 +0000 |
2535 | +++ lib/core/protodefs.h 2012-03-09 15:19:21 +0000 |
2536 | @@ -375,6 +375,20 @@ |
2537 | #define HIP_VER_RES 0x01 /* Version 1, reserved 0 */ |
2538 | #define HIP_USER_VER_RES 0xF0 /* Internal messages */ |
2539 | |
2540 | + |
2541 | +/* HIP certificate types |
2542 | + * (according to RFC 6253) */ |
2543 | +enum hip_cert_type { |
2544 | + HIP_CERT_X509V3, |
2545 | + HIP_CERT_SPKI, |
2546 | + HIP_CERT_X509V3_HASH_URL, |
2547 | + HIP_CERT_SPKI_HASH_URL, |
2548 | + HIP_CERT_X509V3_LDAP_URL, |
2549 | + HIP_CERT_SPKI_LDAP_URL, |
2550 | + HIP_CERT_X509V3_DN, |
2551 | + HIP_CERT_SPKI_DN, |
2552 | +}; |
2553 | + |
2554 | /** |
2555 | * @defgroup hip_ha_controls HIP host association controls |
2556 | * |
2557 | |
2558 | === added directory 'modules/cert' |
2559 | === added directory 'modules/cert/hipd' |
2560 | === renamed file 'hipd/pisa.c' => 'modules/cert/hipd/cert.c' |
2561 | --- hipd/pisa.c 2011-10-25 21:14:16 +0000 |
2562 | +++ modules/cert/hipd/cert.c 2012-03-09 15:19:21 +0000 |
2563 | @@ -1,5 +1,5 @@ |
2564 | /* |
2565 | - * Copyright (c) 2010 Aalto University and RWTH Aachen University. |
2566 | + * Copyright (c) 2010-2012 Aalto University and RWTH Aachen University. |
2567 | * |
2568 | * Permission is hereby granted, free of charge, to any person |
2569 | * obtaining a copy of this software and associated documentation |
2570 | @@ -25,59 +25,179 @@ |
2571 | |
2572 | /** |
2573 | * @file |
2574 | - * This file contains functions that are specific to PISA. They deal with the |
2575 | - * certificate loading. |
2576 | - * |
2577 | - * @brief Functions for certificate loading |
2578 | + * @brief functions to add certificates to R2 and U2 messages |
2579 | */ |
2580 | |
2581 | +#include <stdbool.h> |
2582 | #include <stdio.h> |
2583 | #include <stdlib.h> |
2584 | #include <string.h> |
2585 | |
2586 | -#include "config.h" |
2587 | +#include "hipd/hipd.h" |
2588 | +#include "hipd/pkt_handling.h" |
2589 | +#include "lib/core/builder.h" |
2590 | +#include "lib/core/cert.h" |
2591 | #include "lib/core/debug.h" |
2592 | -#include "hipd.h" |
2593 | -#include "pisa.h" |
2594 | - |
2595 | -#define CERT_MAX_SIZE 1024 |
2596 | - |
2597 | -static char *midauth_cert = NULL; |
2598 | - |
2599 | -/** |
2600 | - * Load a certificate from the file HIPL_SYSCONFDIR/cert and store it in memory |
2601 | - * |
2602 | - * @return 0 on success |
2603 | - */ |
2604 | -static int pisa_load_certificate(void) |
2605 | -{ |
2606 | - FILE *f = NULL; |
2607 | - |
2608 | - free(midauth_cert); |
2609 | - midauth_cert = calloc(1, CERT_MAX_SIZE); |
2610 | - |
2611 | - if (!(f = fopen(HIPL_SYSCONFDIR "/cert", "r"))) { |
2612 | - HIP_ERROR("Could not open certificate file.\n"); |
2613 | - return -1; |
2614 | - } |
2615 | - |
2616 | - if (fread(midauth_cert, CERT_MAX_SIZE - 1, 1, f) == 0) { |
2617 | - perror("fread returned 0"); |
2618 | - } |
2619 | - fclose(f); |
2620 | - return 0; |
2621 | -} |
2622 | - |
2623 | -/** |
2624 | - * Load a certificate from disk and return a pointer to the global |
2625 | - * variable containing it. |
2626 | - * |
2627 | - * @see pisa_load_certificate* |
2628 | - * |
2629 | - * @return pointer to midauth_cert |
2630 | - */ |
2631 | -char *hip_pisa_get_certificate(void) |
2632 | -{ |
2633 | - pisa_load_certificate(); |
2634 | - return midauth_cert; |
2635 | +#include "lib/core/ife.h" |
2636 | +#include "lib/core/protodefs.h" |
2637 | +#include "modules/midauth/hipd/midauth.h" |
2638 | +#include "modules/update/hipd/update.h" |
2639 | +#include "cert.h" |
2640 | + |
2641 | +static X509 *host_cert = NULL; |
2642 | + |
2643 | +/** |
2644 | + * Handler that adds the certificate to an R2 message. |
2645 | + * |
2646 | + * @param msg the message where to add the certificate |
2647 | + * @param certificate the certificate to add to the message |
2648 | + * |
2649 | + * @return 0 on success, negative on error |
2650 | + */ |
2651 | +static int hip_add_certificate(struct hip_common *msg, X509 *certificate) |
2652 | +{ |
2653 | + unsigned char *buf; |
2654 | + int len = 0; |
2655 | + |
2656 | + /* Sanity checks */ |
2657 | + if (!msg) { |
2658 | + HIP_ERROR("Message is NULL\n"); |
2659 | + return -1; |
2660 | + } |
2661 | + if (!certificate) { |
2662 | + HIP_ERROR("Certificate is NULL\n"); |
2663 | + return -1; |
2664 | + } |
2665 | + |
2666 | + /* Encode the certificate to DER and build the certificate parameter. */ |
2667 | + if ((len = cert_X509_to_DER(certificate, &buf)) < 0) { |
2668 | + HIP_ERROR("Encoding error\n"); |
2669 | + return -1; |
2670 | + } |
2671 | + if (hip_build_param_cert(msg, 0, 1, 1, HIP_CERT_X509V3, buf, len)) { |
2672 | + HIP_ERROR("Building of certificate parameter failed.\n"); |
2673 | + return -1; |
2674 | + } |
2675 | + |
2676 | + return 0; |
2677 | +} |
2678 | + |
2679 | +/** |
2680 | + * Handler that adds the certificate to an R2 message. |
2681 | + * |
2682 | + * @param packet_type unused |
2683 | + * @param ha_state unused |
2684 | + * @param ctx the packet context |
2685 | + * |
2686 | + * @return 0 on success, negative on failure |
2687 | + * |
2688 | + * @note: The certificate is regarded non-critical thus the function does |
2689 | + * not fail even if no certificate is available. |
2690 | + */ |
2691 | +static int hip_add_certificate_r2(UNUSED const uint8_t packet_type, |
2692 | + UNUSED const uint32_t ha_state, |
2693 | + struct hip_packet_context *ctx) |
2694 | +{ |
2695 | + if (hip_add_certificate(ctx->output_msg, host_cert)) { |
2696 | + HIP_DEBUG("Sending R2 without certificate.\n"); |
2697 | + } |
2698 | + return 0; |
2699 | +} |
2700 | + |
2701 | +/** |
2702 | + * Handler that adds the certificate to the second or third update message. |
2703 | + * A certificate should only be included if the previous |
2704 | + * update packet contained a middlebox challenge. |
2705 | + * |
2706 | + * @param packet_type unused |
2707 | + * @param ha_state unused |
2708 | + * @param ctx the packet context |
2709 | + * |
2710 | + * @return 0 on success, negative on failure |
2711 | + * |
2712 | + * @note: The certificate is regarded non-critical thus the function does |
2713 | + * not fail even if no certificate is available. |
2714 | + */ |
2715 | +static int hip_add_certificate_update(UNUSED const uint8_t packet_type, |
2716 | + UNUSED const uint32_t ha_state, |
2717 | + struct hip_packet_context *ctx) |
2718 | +{ |
2719 | + if (!host_cert) { |
2720 | + HIP_DEBUG("No certificate available.\n"); |
2721 | + return 0; |
2722 | + } |
2723 | + |
2724 | + /* Include a certificate in the U2 or U3, if available. */ |
2725 | + if (hip_classify_update_type(ctx->input_msg) == FIRST_UPDATE_PACKET || |
2726 | + hip_classify_update_type(ctx->input_msg) == SECOND_UPDATE_PACKET) { |
2727 | + if (hip_get_param_contents(ctx->input_msg, HIP_PARAM_CHALLENGE_REQUEST)) { |
2728 | + if (hip_add_certificate(ctx->output_msg, host_cert)) { |
2729 | + HIP_ERROR("Failed to add certificate to update message.\n"); |
2730 | + return -1; |
2731 | + } |
2732 | + } else { |
2733 | + HIP_DEBUG("No middlebox found in previous update, omitting certificate.\n"); |
2734 | + } |
2735 | + } |
2736 | + |
2737 | + return 0; |
2738 | +} |
2739 | + |
2740 | +/** |
2741 | + * Initialize certificate functionality in the hipd. |
2742 | + * Registers handlers to add the trust point certificate in R2 and U2 messages. |
2743 | + * |
2744 | + * @return 0 on success, negative on error |
2745 | + */ |
2746 | +int hip_cert_init(void) |
2747 | +{ |
2748 | + if (hip_register_handle_function(HIP_I2, HIP_STATE_NONE, |
2749 | + &hip_add_certificate_r2, 40500)) { |
2750 | + HIP_ERROR("Error on registering certificate handle function.\n"); |
2751 | + return -1; |
2752 | + } |
2753 | + if (hip_register_handle_function(HIP_I2, HIP_STATE_UNASSOCIATED, |
2754 | + &hip_add_certificate_r2, 40500)) { |
2755 | + HIP_ERROR("Error on registering certificate handle function.\n"); |
2756 | + return -1; |
2757 | + } |
2758 | + if (hip_register_handle_function(HIP_I2, HIP_STATE_I1_SENT, |
2759 | + &hip_add_certificate_r2, 40500)) { |
2760 | + HIP_ERROR("Error on registering certificate handle function.\n"); |
2761 | + return -1; |
2762 | + } |
2763 | + if (hip_register_handle_function(HIP_I2, HIP_STATE_I2_SENT, |
2764 | + &hip_add_certificate_r2, 40500)) { |
2765 | + HIP_ERROR("Error on registering certificate handle function.\n"); |
2766 | + return -1; |
2767 | + } |
2768 | + if (hip_register_handle_function(HIP_I2, HIP_STATE_R2_SENT, |
2769 | + &hip_add_certificate_r2, 40500)) { |
2770 | + HIP_ERROR("Error on registering certificate handle function.\n"); |
2771 | + return -1; |
2772 | + } |
2773 | + if (hip_register_handle_function(HIP_I2, HIP_STATE_ESTABLISHED, |
2774 | + &hip_add_certificate_r2, 40500)) { |
2775 | + HIP_ERROR("Error on registering certificate handle function.\n"); |
2776 | + return -1; |
2777 | + } |
2778 | + if (hip_register_handle_function(HIP_UPDATE, HIP_STATE_ESTABLISHED, |
2779 | + &hip_add_certificate_update, 20752)) { |
2780 | + HIP_ERROR("Error on registering certificate handle function.\n"); |
2781 | + return -1; |
2782 | + } |
2783 | + if (hip_register_handle_function(HIP_UPDATE, HIP_STATE_R2_SENT, |
2784 | + &hip_add_certificate_update, 20752)) { |
2785 | + HIP_ERROR("Error on registering certificate handle function.\n"); |
2786 | + return -1; |
2787 | + } |
2788 | + |
2789 | + if (!(host_cert = cert_load_x509_certificate(HIPL_SYSCONFDIR "/host-cert.der", |
2790 | + ENCODING_FORMAT_DER))) { |
2791 | + HIP_DEBUG("Could not load certificate.\n"); |
2792 | + } |
2793 | + |
2794 | + HIP_DEBUG("certificates initialized\n"); |
2795 | + |
2796 | + return 0; |
2797 | } |
2798 | |
2799 | === renamed file 'hipd/pisa.h' => 'modules/cert/hipd/cert.h' |
2800 | --- hipd/pisa.h 2011-11-25 17:56:24 +0000 |
2801 | +++ modules/cert/hipd/cert.h 2012-03-09 15:19:21 +0000 |
2802 | @@ -1,5 +1,5 @@ |
2803 | /* |
2804 | - * Copyright (c) 2010 Aalto University and RWTH Aachen University. |
2805 | + * Copyright (c) 2010-2011 Aalto University and RWTH Aachen University. |
2806 | * |
2807 | * Permission is hereby granted, free of charge, to any person |
2808 | * obtaining a copy of this software and associated documentation |
2809 | @@ -23,22 +23,9 @@ |
2810 | * OTHER DEALINGS IN THE SOFTWARE. |
2811 | */ |
2812 | |
2813 | -/** |
2814 | - * @file |
2815 | - * This file contains function declarations specific to PISA. They deal with the |
2816 | - * certificate loading. |
2817 | - * |
2818 | - * @brief Functions declarations for certificate loading |
2819 | - */ |
2820 | - |
2821 | -#ifndef HIPL_HIPD_PISA_H |
2822 | -#define HIPL_HIPD_PISA_H |
2823 | - |
2824 | -/** |
2825 | - * Get the certificate text that will be appended to R2 and U2 packets |
2826 | - * |
2827 | - * @return pointer to the certificate text |
2828 | - */ |
2829 | -char *hip_pisa_get_certificate(void); |
2830 | - |
2831 | -#endif /* HIPL_HIPD_PISA_H */ |
2832 | +#ifndef HIPL_MODULES_CERT_HIPD_CERT_H |
2833 | +#define HIPL_MODULES_CERT_HIPD_CERT_H |
2834 | + |
2835 | +int hip_cert_init(void); |
2836 | + |
2837 | +#endif /* HIPL_MODULES_CERT_HIPD_CERT_H */ |
2838 | |
2839 | === added file 'modules/cert/module_info.xml' |
2840 | --- modules/cert/module_info.xml 1970-01-01 00:00:00 +0000 |
2841 | +++ modules/cert/module_info.xml 2012-03-09 15:19:21 +0000 |
2842 | @@ -0,0 +1,23 @@ |
2843 | +<?xml version="1.0" encoding="UTF-8"?> |
2844 | + |
2845 | +<!-- Mandatory: name, version --> |
2846 | +<module |
2847 | + name="cert" |
2848 | + version="0.0.1" |
2849 | + description="certificate exchange for the HIP daemon." |
2850 | + developer="" |
2851 | + bugaddress="hipl-users@freelists.org" |
2852 | + webpage="http://infrahip.hiit.fi/"> |
2853 | + |
2854 | + <requires> |
2855 | + <module name="update" minversion="0.0.1" /> |
2856 | + <module name="midauth" minversion="0.0.1" /> |
2857 | + </requires> |
2858 | + |
2859 | + <!-- Mandatory: name, header_file, init_function --> |
2860 | + <application |
2861 | + name="hipd" |
2862 | + header_file="modules/cert/hipd/cert.h" |
2863 | + init_function="hip_cert_init" /> |
2864 | +</module> |
2865 | + |
2866 | |
2867 | === modified file 'modules/update/hipd/update.c' (properties changed: -x to +x) |
2868 | === modified file 'test/check_lib_core.c' |
2869 | --- test/check_lib_core.c 2012-03-01 14:06:24 +0000 |
2870 | +++ test/check_lib_core.c 2012-03-09 15:19:21 +0000 |
2871 | @@ -37,6 +37,7 @@ |
2872 | { |
2873 | int number_failed; |
2874 | SRunner *sr = srunner_create(lib_core_hit()); |
2875 | + srunner_add_suite(sr, lib_core_cert()); |
2876 | srunner_add_suite(sr, lib_core_hostid()); |
2877 | srunner_add_suite(sr, lib_core_solve()); |
2878 | srunner_add_suite(sr, lib_core_straddr()); |
2879 | |
2880 | === added file 'test/lib/core/cert.c' |
2881 | --- test/lib/core/cert.c 1970-01-01 00:00:00 +0000 |
2882 | +++ test/lib/core/cert.c 2012-03-09 15:19:21 +0000 |
2883 | @@ -0,0 +1,189 @@ |
2884 | +/* |
2885 | + * Copyright (c) 2011 Aalto University and RWTH Aachen University. |
2886 | + * |
2887 | + * Permission is hereby granted, free of charge, to any person |
2888 | + * obtaining a copy of this software and associated documentation |
2889 | + * files (the "Software"), to deal in the Software without |
2890 | + * restriction, including without limitation the rights to use, |
2891 | + * copy, modify, merge, publish, distribute, sublicense, and/or sell |
2892 | + * copies of the Software, and to permit persons to whom the |
2893 | + * Software is furnished to do so, subject to the following |
2894 | + * conditions: |
2895 | + * |
2896 | + * The above copyright notice and this permission notice shall be |
2897 | + * included in all copies or substantial portions of the Software. |
2898 | + * |
2899 | + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, |
2900 | + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES |
2901 | + * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND |
2902 | + * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT |
2903 | + * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, |
2904 | + * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING |
2905 | + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR |
2906 | + * OTHER DEALINGS IN THE SOFTWARE. |
2907 | + */ |
2908 | + |
2909 | +#include <check.h> |
2910 | +#include <stdlib.h> |
2911 | +#include <string.h> |
2912 | +#include <stdio.h> |
2913 | + |
2914 | +#include "lib/core/cert.h" |
2915 | +#include "lib/core/crypto.h" |
2916 | +#include "lib/core/ife.h" |
2917 | +#include "lib/core/protodefs.h" |
2918 | +#include "config.h" |
2919 | +#include "test_suites.h" |
2920 | + |
2921 | +#define TEST_CERT HIPL_SOURCEDIR "/test/lib/core/test_cert.pem" |
2922 | +#define TEST_KEY HIPL_SOURCEDIR "/test/lib/core/test_key.pem" |
2923 | + |
2924 | +START_TEST(test_cert_load_x509_certificate) |
2925 | +{ |
2926 | + X509 *cert = NULL; |
2927 | + |
2928 | + HIP_DEBUG("Test loading of X509 certificates.\n"); |
2929 | + |
2930 | + fail_unless((cert = cert_load_x509_certificate(TEST_CERT, |
2931 | + ENCODING_FORMAT_PEM)) != NULL, |
2932 | + NULL); |
2933 | + fail_unless((cert = cert_load_x509_certificate("non_existing_cert.pem", |
2934 | + ENCODING_FORMAT_PEM)) == NULL, |
2935 | + NULL); |
2936 | + fail_unless((cert = cert_load_x509_certificate(NULL, |
2937 | + ENCODING_FORMAT_PEM)) == NULL, |
2938 | + NULL); |
2939 | + |
2940 | + X509_free(cert); |
2941 | + HIP_DEBUG("Successfully passed tests for loading X509 certificates.\n"); |
2942 | +} |
2943 | +END_TEST |
2944 | + |
2945 | +START_TEST(test_cert_DER_encoding) |
2946 | +{ |
2947 | + int len = 0; |
2948 | + X509 *cert = NULL; |
2949 | + X509 *cert_decoded = NULL; |
2950 | + unsigned char *buf = NULL; |
2951 | + |
2952 | + HIP_DEBUG("Test DER en/decoding of X509 certificates.\n"); |
2953 | + |
2954 | + fail_unless((cert = cert_load_x509_certificate(TEST_CERT, |
2955 | + ENCODING_FORMAT_PEM)) != NULL, |
2956 | + NULL); |
2957 | + fail_unless((len = cert_X509_to_DER(cert, &buf)) > 0, NULL); |
2958 | + fail_unless((cert_decoded = cert_DER_to_X509(buf, len)) != NULL, NULL); |
2959 | + fail_unless(X509_cmp(cert, cert_decoded) == 0, NULL); |
2960 | + |
2961 | + fail_unless((len = cert_X509_to_DER(NULL, &buf)) < 0, NULL); |
2962 | + fail_unless((len = cert_X509_to_DER(cert, NULL)) < 0, NULL); |
2963 | + fail_unless((len = cert_X509_to_DER(NULL, NULL)) < 0, NULL); |
2964 | + |
2965 | + fail_unless((cert_decoded = cert_DER_to_X509(NULL, len)) == NULL, NULL); |
2966 | + fail_unless((cert_decoded = cert_DER_to_X509(buf, len - 1)) == NULL, NULL); |
2967 | + fail_unless((cert_decoded = cert_DER_to_X509(buf, len + 1)) == NULL, NULL); |
2968 | + fail_unless((cert_decoded = cert_DER_to_X509(buf, 0)) == NULL, NULL); |
2969 | + |
2970 | + X509_free(cert); |
2971 | + X509_free(cert_decoded); |
2972 | + |
2973 | + HIP_DEBUG("Successfully passed tests for DER en/decoding of X509 certificates.\n"); |
2974 | +} |
2975 | + |
2976 | +END_TEST |
2977 | + |
2978 | +START_TEST(test_cert_match_public_key) |
2979 | +{ |
2980 | + int err = 0; |
2981 | + RSA *rsa = NULL; |
2982 | + X509 *cert = NULL; |
2983 | + EVP_PKEY *pkey = NULL; |
2984 | + |
2985 | + HIP_DEBUG("Test matching of public keys.\n"); |
2986 | + |
2987 | + fail_unless((err = load_rsa_private_key(TEST_KEY, &rsa)) == 0, NULL); |
2988 | + fail_unless((cert = cert_load_x509_certificate(TEST_CERT, |
2989 | + ENCODING_FORMAT_PEM)) != NULL, |
2990 | + NULL); |
2991 | + pkey = EVP_PKEY_new(); |
2992 | + EVP_PKEY_assign_RSA(pkey, rsa); |
2993 | + fail_unless((err = cert_match_public_key(cert, pkey)) == 1, NULL); |
2994 | + |
2995 | + fail_unless((err = cert_match_public_key(NULL, pkey)) == 0, NULL); |
2996 | + fail_unless((err = cert_match_public_key(cert, NULL)) == 0, NULL); |
2997 | + fail_unless((err = cert_match_public_key(NULL, NULL)) == 0, NULL); |
2998 | + |
2999 | + EVP_PKEY_free(pkey); |
3000 | + X509_free(cert); |
3001 | + |
3002 | + HIP_DEBUG("Successfully passed test for matching of public keys.\n"); |
3003 | +} |
3004 | + |
3005 | +END_TEST |
3006 | + |
3007 | +START_TEST(test_cert_verify_chain) |
3008 | +{ |
3009 | + int err = 0; |
3010 | + X509 *cert = NULL; |
3011 | + STACK_OF(X509) *chain = NULL; |
3012 | + |
3013 | + HIP_DEBUG("Test verification of certificate chains.\n"); |
3014 | + |
3015 | + fail_unless((cert = cert_load_x509_certificate(TEST_CERT, |
3016 | + ENCODING_FORMAT_PEM)) != NULL, |
3017 | + NULL); |
3018 | + fail_unless((chain = sk_X509_new_null()) != NULL, NULL); |
3019 | + sk_X509_push(chain, cert); |
3020 | + fail_unless((err = cert_verify_chain(cert, NULL, chain, NULL)) == 0, NULL); |
3021 | + |
3022 | + fail_unless((err = cert_verify_chain(NULL, NULL, chain, NULL)) != 0, NULL); |
3023 | + fail_unless((err = cert_verify_chain(cert, NULL, NULL, NULL)) != 0, NULL); |
3024 | + |
3025 | + HIP_DEBUG("Successfully passed test for verification of certificate chains.\n"); |
3026 | +} |
3027 | + |
3028 | +END_TEST |
3029 | + |
3030 | +START_TEST(test_cert_get_X509_from_msg) |
3031 | +{ |
3032 | + int len = 0; |
3033 | + X509 *cert = NULL, *cert2 = NULL; |
3034 | + struct hip_common *msg = NULL; |
3035 | + unsigned char *buf = NULL; |
3036 | + |
3037 | + HIP_DEBUG("Test certificate extraction functionality.\n"); |
3038 | + |
3039 | + fail_unless((cert = cert_load_x509_certificate(TEST_CERT, |
3040 | + ENCODING_FORMAT_PEM)) != NULL, |
3041 | + NULL); |
3042 | + msg = hip_msg_alloc(); |
3043 | + hip_build_network_hdr(msg, HIP_UPDATE, 0, &in6addr_any, &in6addr_any); |
3044 | + fail_unless((len = cert_X509_to_DER(cert, &buf)) > 0, NULL); |
3045 | + fail_unless(hip_build_param_cert(msg, 0, 1, 1, HIP_CERT_X509V3, buf, len) == 0, NULL); |
3046 | + fail_unless((cert2 = cert_get_X509_from_msg(msg)) != NULL, NULL); |
3047 | + fail_unless(X509_cmp(cert, cert2) == 0, NULL); |
3048 | + |
3049 | + X509_free(cert); |
3050 | + X509_free(cert2); |
3051 | + |
3052 | + HIP_DEBUG("Successfully passed test for certificate extraction functionality.\n"); |
3053 | +} |
3054 | + |
3055 | +END_TEST |
3056 | + |
3057 | + |
3058 | +Suite *lib_core_cert(void) |
3059 | +{ |
3060 | + Suite *s = suite_create("lib/core/cert"); |
3061 | + |
3062 | + TCase *tc_core = tcase_create("Core"); |
3063 | + tcase_add_test(tc_core, test_cert_load_x509_certificate); |
3064 | + tcase_add_test(tc_core, test_cert_DER_encoding); |
3065 | + tcase_add_test(tc_core, test_cert_match_public_key); |
3066 | + tcase_add_test(tc_core, test_cert_verify_chain); |
3067 | + tcase_add_test(tc_core, test_cert_get_X509_from_msg); |
3068 | + |
3069 | + suite_add_tcase(s, tc_core); |
3070 | + |
3071 | + return s; |
3072 | +} |
3073 | |
3074 | === added file 'test/lib/core/test_cert.pem' |
3075 | --- test/lib/core/test_cert.pem 1970-01-01 00:00:00 +0000 |
3076 | +++ test/lib/core/test_cert.pem 2012-03-09 15:19:21 +0000 |
3077 | @@ -0,0 +1,15 @@ |
3078 | +-----BEGIN CERTIFICATE----- |
3079 | +MIICWTCCAcKgAwIBAgIJAPRDK58Gc992MA0GCSqGSIb3DQEBBQUAMCgxCzAJBgNV |
3080 | +BAYTAkRFMRkwFwYDVQQDExBUZXN0IENlcnRpZmljYXRlMB4XDTExMTExNTA4NDYx |
3081 | +MloXDTE0MDgxMTA4NDYxMlowKDELMAkGA1UEBhMCREUxGTAXBgNVBAMTEFRlc3Qg |
3082 | +Q2VydGlmaWNhdGUwgZ8wDQYJKoZIhvcNAQEBBQADgY0AMIGJAoGBAMn5azBSwPlu |
3083 | +DIzEhd6fGdo1+ze9uS+i+AbifvjHKYaDwDZktANnUmTuLNAXoeVtFi5GH/5aczUx |
3084 | +rFaW+XT33oO1OjotZOHvoQd5cVAvXTtzuJj9PnBtA0lkrQ36f765p65Id0+Xme3o |
3085 | +sXfqLsJy12C23RjisPgAo0hsLUFXt+FZAgMBAAGjgYowgYcwHQYDVR0OBBYEFGrj |
3086 | +JefuwL7xAFj9NZoDVksjz1JBMFgGA1UdIwRRME+AFGrjJefuwL7xAFj9NZoDVksj |
3087 | +z1JBoSykKjAoMQswCQYDVQQGEwJERTEZMBcGA1UEAxMQVGVzdCBDZXJ0aWZpY2F0 |
3088 | +ZYIJAPRDK58Gc992MAwGA1UdEwQFMAMBAf8wDQYJKoZIhvcNAQEFBQADgYEAKX5Q |
3089 | +0di8aNk1Js5Sk6QstSWwoVT9DUNZ8wKKRZVHy4kSL7dGMNGRPyNydzJmKeacbZJ0 |
3090 | +wM64rMMC1E8Wnyo+7eS1k9NKgaR5S1K6SVTfgP0HYIeJquD5Im/KW3aMz/q5CWdV |
3091 | +IZtpTC2/1YsK+dVlvvcYRxnSTpIEd/pmu574lis= |
3092 | +-----END CERTIFICATE----- |
3093 | |
3094 | === added file 'test/lib/core/test_key.pem' |
3095 | --- test/lib/core/test_key.pem 1970-01-01 00:00:00 +0000 |
3096 | +++ test/lib/core/test_key.pem 2012-03-09 15:19:21 +0000 |
3097 | @@ -0,0 +1,15 @@ |
3098 | +-----BEGIN RSA PRIVATE KEY----- |
3099 | +MIICXAIBAAKBgQDJ+WswUsD5bgyMxIXenxnaNfs3vbkvovgG4n74xymGg8A2ZLQD |
3100 | +Z1Jk7izQF6HlbRYuRh/+WnM1MaxWlvl0996DtTo6LWTh76EHeXFQL107c7iY/T5w |
3101 | +bQNJZK0N+n++uaeuSHdPl5nt6LF36i7Cctdgtt0Y4rD4AKNIbC1BV7fhWQIDAQAB |
3102 | +AoGAT1OS8evOtyit7SvSmFlMwhOpk38EmN0dJTcYP4WZnadpevOacCvIhLO3DhP6 |
3103 | +Fi3+JDaOokvMK/xSf7/UQkiIL+dwY5FtWtG6K+T1WI4+DR7ULShr82jh4KemhYv3 |
3104 | +Xz6PvEBIUrf64VfsNsAzoWvbwum/Ev1XzFn5YS4/EW3ApnECQQD2YW6tTjzyq3y7 |
3105 | +sgil9/VtUrXpPi5Ekm8l/bFW2Ijwin03g6J+YvkDNIq5Wwyka7lBOLwpdSpzT2qB |
3106 | +70Ne1nlfAkEA0dwlgou4xOVVmbtTb40FxIFgd2gDQO8bUFEa+TdPWLLxz9yxHQ7D |
3107 | +YROYh5Gdi0u4lz0KNex/6zyaP7E+utbIRwJAexNc2FH2/DpSCuj6jP36qevhV2xq |
3108 | +bHLB9zZtujZc4dwshOjK6VvDjKhYjBNBk3kEh+IxjHwtAoEvcUz2WI/G/QJAcMr5 |
3109 | +/ihKrsj0MSRVu+b36p3+0y68UPIypABzlu77XpkPDsF3ED8XE94MZREGtA+GrwLH |
3110 | +siPivPRdk04YgSNfkQJBAMhHvxL5xsb31bu8h7kxoYHj/XuqJxyToTcqksr7M1RO |
3111 | +z33Bid+znwnB7n8CLFpV3iqF14xbRKiPlc//wVNWtZ8= |
3112 | +-----END RSA PRIVATE KEY----- |
3113 | |
3114 | === modified file 'test/lib/core/test_suites.h' |
3115 | --- test/lib/core/test_suites.h 2012-03-01 14:06:24 +0000 |
3116 | +++ test/lib/core/test_suites.h 2012-03-09 15:19:21 +0000 |
3117 | @@ -28,6 +28,7 @@ |
3118 | |
3119 | #include <check.h> |
3120 | |
3121 | +Suite *lib_core_cert(void); |
3122 | Suite *lib_core_crypto(void); |
3123 | Suite *lib_core_hit(void); |
3124 | Suite *lib_core_hostid(void); |
3125 | |
3126 | === modified file 'tools/hipl_autobuild.sh' |
3127 | --- tools/hipl_autobuild.sh 2012-02-28 16:54:46 +0000 |
3128 | +++ tools/hipl_autobuild.sh 2012-03-09 15:19:21 +0000 |
3129 | @@ -169,7 +169,7 @@ |
3130 | run_program "make $MAKEOPTS check" |
3131 | |
3132 | # minimal configuration |
3133 | -compile --enable-firewall --disable-rvs --disable-profiling --disable-debug --disable-performance --with-nomodules=heartbeat,update,heartbeat_update,midauth |
3134 | +compile --enable-firewall --disable-rvs --disable-profiling --disable-debug --disable-performance --with-nomodules=heartbeat,update,heartbeat_update,midauth,cert |
3135 | |
3136 | # Max compile coverage configuration |
3137 | FEATURES_ALL="--enable-firewall --enable-rvs --enable-profiling --disable-debug --enable-performance" |
3138 | @@ -185,9 +185,6 @@ |
3139 | # FIXME: Disabled until the tree compiles with this optimization level. |
3140 | #compile $FEATURES_ALL CFLAGS="-O3" |
3141 | |
3142 | -# Without modules |
3143 | -compile --with-nomodules=heartbeat,update,heartbeat_update,midauth |
3144 | - |
3145 | # test binary distribution packages |
3146 | # This is run as the last test because it can have sideeffects on the |
3147 | # other standard configurations. |
Did I understand correctly, is the certificate parameter added only when the corresponding non-automatically generated file exists?
Can you remind why the PISA stuff was removed?