Merge lp:~fahad-aizaz/hipl/cert-config into lp:hipl

Proposed by Fahad Aizaz on 2012-02-20
Status: Needs review
Proposed branch: lp:~fahad-aizaz/hipl/cert-config
Merge into: lp:hipl
Diff against target: 3876 lines (+6/-3611)
21 files modified
Makefile.am (+1/-10)
hipd/cert.c (+0/-1029)
hipd/cert.h (+0/-48)
hipd/init.c (+1/-82)
hipd/input.c (+0/-1)
hipd/output.c (+0/-1)
hipd/pisa.c (+0/-83)
hipd/pisa.h (+0/-44)
hipd/user.c (+1/-36)
hipfw/conntrack.c (+3/-3)
hipfw/hipfw.c (+0/-7)
hipfw/pisa.c (+0/-575)
hipfw/pisa.h (+0/-48)
hipfw/pisa_cert.c (+0/-205)
hipfw/pisa_cert.h (+0/-47)
lib/core/builder.c (+0/-101)
lib/core/builder.h (+0/-6)
lib/core/certtools.c (+0/-856)
lib/core/certtools.h (+0/-79)
test/certteststub.c (+0/-196)
tools/pisacert.c (+0/-154)
To merge this branch: bzr merge lp:~fahad-aizaz/hipl/cert-config
Reviewer Review Type Date Requested Status
Diego Biurrun 2012-02-20 Resubmit on 2012-03-16
Miika Komu 2012-02-20 Approve on 2012-02-21
HIPL core team 2012-02-20 Pending
René Hummen 2012-02-20 Pending
Review via email: mp+93901@code.launchpad.net

This proposal supersedes a proposal from 2012-02-19.

Description of the change

Configuration file code removal. Continuing the removal of configuration file code removal. Though this branch also contain some other changes in relation to 'hip_cert.conf' configuration file.

As decided by hipl core team, there is no more requirement of 'hip_cert.conf' file anymore to be part of HIPL codebase at all. So the following changes has been done.

1. The removal of runtime generation of 'hip_cert.conf' file.
2. The references to the functions that read, sign and verify certificates.

A lot of related code is also removed. Significantly the code files:

1. certtools.h and certtools.c
2. test/certteststub.c and tools/pisacert.c
3. hipfw/pisa.c hipfw/pisa.h hipd/pisa.c hipd/pisa.h (i couldn't find any references to the functions defined in these files)
4. Redundant code was removed (builder.c and builder.h) They defined functions that were used in certtools.c/h which is
    removed.
5. hipfw/pisa_cert.c/h also contained functions which were not referenced anywhere in hiplcodebase.

Since my knowledge of hip certifcate handling is limited. Please correct me if i have removed any code which I am not suppose to.

To post a comment you must log in.
Miika Komu (miika-iki) : Posted in a previous version of this proposal
review: Approve
Diego Biurrun (diego-biurrun) wrote : Posted in a previous version of this proposal

 review needs-fixing

On Sun, Feb 19, 2012 at 12:29:18PM +0000, Fahad Aizaz wrote:
>
> Configuration file code removal. Continuing the removal of configuration file code removal. Though this branch also contain some other changes in relation to 'hip_cert.conf' configuration file.
>
> As decided by hipl core team, there is no more requirement of 'hip_cert.conf' file anymore to be part of HIPL codebase at all. So the following changes has been done.
>
> 1. The removal of runtime generation of 'hip_cert.conf' file.
> 2. The references to the functions that read, sign and verify certificates.
>
> Note: here the references to the function from the codebase is removed. But the files containing the declarations and definitions are still not yet removed. I need your approval for doing that. (files: cert.h, cert.c). Please also note I looked in the codebase for anymore references towards the functions in these files and safely I can say I didn't find any. Therefore these files are feasible to be removed from the HIPL.
>
> There exist some other helper functions (such as opening configuration file, read it section by section) being used in functions defined in 'cert.c' but are part of hipl core library. (lib/core/certtools.c/h). Though these functions are referenced from a test code, but also being used in the firewall code with PISA specific handling of SPKI certificates.

I say nuke them all.

Diego

review: Needs Fixing
Miika Komu (miika-iki) wrote :

Fine by me. Btw, does this mean that we will not have any support for certificates?

review: Approve
Diego Biurrun (diego-biurrun) wrote :

 review needs-info

On Mon, Feb 20, 2012 at 09:56:24PM +0000, Fahad Aizaz wrote:
> Fahad Aizaz has proposed merging lp:~fahad-aizaz/hipl/cert-config into lp:hipl.

I don't think this is compatible with the pisa certificate branch.

Diego

review: Needs Information
Fahad Aizaz (fahad-aizaz) wrote :

On 02/21/2012 02:23 PM, Diego Biurrun wrote:
> Review: Needs Information
>
> review needs-info
>
> On Mon, Feb 20, 2012 at 09:56:24PM +0000, Fahad Aizaz wrote:
>> Fahad Aizaz has proposed merging lp:~fahad-aizaz/hipl/cert-config into lp:hipl.
>
> I don't think this is compatible with the pisa certificate branch.

In a way you are absolutely right. As far as I could look into the code,
I didn't find any references to certificate generation, signing etc.
Perhaps that what Renè meant, to introduce a complete certificates
functionality.

I removed certtools.c/h and moving from there removed the code that
either depends on the functions defined in this file or functions that
are referenced from the functions in this file.

I am not sure, whether this part of the code was being used by anyother
part of hipl codebase other than the test code.

regards,
Fahad

Diego Biurrun (diego-biurrun) wrote :

 review resubmit

On Tue, Feb 21, 2012 at 02:19:28PM +0100, Diego Biurrun wrote:
> On Mon, Feb 20, 2012 at 09:56:24PM +0000, Fahad Aizaz wrote:
> > Fahad Aizaz has proposed merging lp:~fahad-aizaz/hipl/cert-config into lp:hipl.
>
> I don't think this is compatible with the pisa certificate branch.

That branch has now landed on trunk, please redo your branch on top of
current trunk.

Diego

review: Resubmit

Unmerged revisions

6295. By Fahad Aizaz on 2012-02-20

Missing file to be removed from Makefile

6294. By Fahad Aizaz on 2012-02-20

Removing useless code.

The code that was related to reading, signing and verfication of
certificates is removed.

Starting from certtools.c/h which contains code for reading certificate
configuration file, reading it section by section, verifictaion etc
is removed.

certtools.c uses functions defined in builder.c; thus these functions
are also removed since they are no longer required.

hipfw/pisa.c/.h uses also functions from certtools.c and thus removed.
hipfw/pisa_cert.c/.h uses also functions from certtools.c and is removed.

certteststub and pisacert.c were the only code files generating and
testing certificates and thus are removed.

6293. By Fahad Aizaz on 2012-02-20

Adding, removing and fixing the redundant code.

This commit contains the files which contained headers of removed code files
having the certificate functionality which is no longer required.

Thus the headers were removed from the following files and also the
the redundant functions in case "hipfw.c" is removed.

6292. By Fahad Aizaz on 2012-02-20

Cosmetics: stylecheck changes that were found and fixed.

6291. By Fahad Aizaz on 2012-02-20

Fixing Makefile to handle the removed code and let it compile properly.

6290. By Fahad Aizaz on 2012-02-20

Removing certificate related code.

The code was utilized by other library functions defined in the file
"certtools.c". Since "certtools.c" is no longer required thus these
functions were also redundant and therefore removed from the codebase.

6289. By Fahad Aizaz on 2012-02-20

Removing files that are no longer required from make.

6288. By Fahad Aizaz on 2012-02-20

Certificate code for signing and verification removal.

As agreed, the certificate signing and verification code is no longer required.
And therefore is being removed from hipl codebase. With it any reference
to the headers are also removed.

6287. By Fahad Aizaz on 2012-02-19

The references for certificate sigining and verifications removal.

The references to the functions that are used to sign and verify
certificates are removed. (As they are no longer required)

Note: this change makes the files cert.c and cert.h and all the functions
declared and defined in these files redundant.

6286. By Fahad Aizaz on 2012-02-19

Removing configuration file generation code.

The cofiguration file 'hip_cert.conf' that is being generated at runtime
is removed from the hipl code base.

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
=== modified file 'Makefile.am'
--- Makefile.am 2012-02-13 11:20:22 +0000
+++ Makefile.am 2012-02-20 21:55:24 +0000
@@ -35,11 +35,9 @@
35EXTRA_DIST += $(wildcard $(addprefix $(srcdir)/tools/,*.cfg *.pl *.sh *.xml))35EXTRA_DIST += $(wildcard $(addprefix $(srcdir)/tools/,*.cfg *.pl *.sh *.xml))
36EXTRA_DIST += $(wildcard $(addprefix $(srcdir)/hipfw/,*.cfg))36EXTRA_DIST += $(wildcard $(addprefix $(srcdir)/hipfw/,*.cfg))
37EXTRA_DIST += $(HIPL_HEADER_LIST)37EXTRA_DIST += $(HIPL_HEADER_LIST)
38EXTRA_DIST += hipd/pisa.c hipfw/pisa.c hipfw/pisa_cert.c
3938
40### user programs ###39### user programs ###
41bin_PROGRAMS = test/auth_performance \40bin_PROGRAMS = test/auth_performance \
42 test/certteststub \
43 test/hc_performance41 test/hc_performance
4442
45if HIP_PERFORMANCE43if HIP_PERFORMANCE
@@ -49,8 +47,7 @@
4947
50### superuser programs ###48### superuser programs ###
51sbin_PROGRAMS = hipd/hipd \49sbin_PROGRAMS = hipd/hipd \
52 tools/hipconf \50 tools/hipconf
53 tools/pisacert
5451
55if HIP_FIREWALL52if HIP_FIREWALL
56sbin_PROGRAMS += hipfw/hipfw53sbin_PROGRAMS += hipfw/hipfw
@@ -84,7 +81,6 @@
84### source declarations ###81### source declarations ###
8582
86test_auth_performance_SOURCES = test/auth_performance.c83test_auth_performance_SOURCES = test/auth_performance.c
87test_certteststub_SOURCES = test/certteststub.c
88test_dh_performance_SOURCES = test/dh_performance.c84test_dh_performance_SOURCES = test/dh_performance.c
89test_fw_port_bindings_performance_SOURCES = hipfw/file_buffer.c \85test_fw_port_bindings_performance_SOURCES = hipfw/file_buffer.c \
90 hipfw/line_parser.c \86 hipfw/line_parser.c \
@@ -93,10 +89,8 @@
93test_hc_performance_SOURCES = test/hc_performance.c89test_hc_performance_SOURCES = test/hc_performance.c
9490
95tools_hipconf_SOURCES = tools/hipconf.c91tools_hipconf_SOURCES = tools/hipconf.c
96tools_pisacert_SOURCES = tools/pisacert.c
9792
98hipd_hipd_sources = hipd/accessor.c \93hipd_hipd_sources = hipd/accessor.c \
99 hipd/cert.c \
100 hipd/close.c \94 hipd/close.c \
101 hipd/configfilereader.c \95 hipd/configfilereader.c \
102 hipd/cookie.c \96 hipd/cookie.c \
@@ -175,7 +169,6 @@
175169
176lib_core_libhipcore_la_SOURCES = lib/core/builder.c \170lib_core_libhipcore_la_SOURCES = lib/core/builder.c \
177 lib/core/capability.c \171 lib/core/capability.c \
178 lib/core/certtools.c \
179 lib/core/conf.c \172 lib/core/conf.c \
180 lib/core/crypto.c \173 lib/core/crypto.c \
181 lib/core/debug.c \174 lib/core/debug.c \
@@ -251,12 +244,10 @@
251test_check_lib_core_LDADD = lib/core/libhipcore.la244test_check_lib_core_LDADD = lib/core/libhipcore.la
252test_check_lib_tool_LDADD = lib/core/libhipcore.la245test_check_lib_tool_LDADD = lib/core/libhipcore.la
253test_check_modules_midauth_LDADD = lib/core/libhipcore.la246test_check_modules_midauth_LDADD = lib/core/libhipcore.la
254test_certteststub_LDADD = lib/core/libhipcore.la
255test_dh_performance_LDADD = lib/core/libhipcore.la247test_dh_performance_LDADD = lib/core/libhipcore.la
256test_fw_port_bindings_performance_LDADD = lib/core/libhipcore.la248test_fw_port_bindings_performance_LDADD = lib/core/libhipcore.la
257test_hc_performance_LDADD = lib/core/libhipcore.la249test_hc_performance_LDADD = lib/core/libhipcore.la
258tools_hipconf_LDADD = lib/core/libhipcore.la250tools_hipconf_LDADD = lib/core/libhipcore.la
259tools_pisacert_LDADD = lib/core/libhipcore.la
260251
261### dynamic library dependencies ###252### dynamic library dependencies ###
262253
263254
=== removed file 'hipd/cert.c'
--- hipd/cert.c 2012-01-16 22:12:49 +0000
+++ hipd/cert.c 1970-01-01 00:00:00 +0000
@@ -1,1029 +0,0 @@
1/*
2 * Copyright (c) 2010-2012 Aalto University and RWTH Aachen University.
3 *
4 * Permission is hereby granted, free of charge, to any person
5 * obtaining a copy of this software and associated documentation
6 * files (the "Software"), to deal in the Software without
7 * restriction, including without limitation the rights to use,
8 * copy, modify, merge, publish, distribute, sublicense, and/or sell
9 * copies of the Software, and to permit persons to whom the
10 * Software is furnished to do so, subject to the following
11 * conditions:
12 *
13 * The above copyright notice and this permission notice shall be
14 * included in all copies or substantial portions of the Software.
15 *
16 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
17 * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
18 * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
19 * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
20 * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
21 * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
22 * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
23 * OTHER DEALINGS IN THE SOFTWARE.
24 */
25
26/**
27 * @file
28 *
29 * This file defines the certificate signing and verification
30 * functions to use with HIP
31 */
32
33#include <errno.h>
34#include <stdint.h>
35#include <stdio.h>
36#include <stdlib.h>
37#include <string.h>
38#include <arpa/inet.h>
39#include <openssl/conf.h>
40#include <openssl/dsa.h>
41#include <openssl/err.h>
42#include <openssl/evp.h>
43#include <openssl/rsa.h>
44#include <openssl/x509.h>
45#include <openssl/x509v3.h>
46
47#include "lib/core/builder.h"
48#include "lib/core/certtools.h"
49#include "lib/core/common.h"
50#include "lib/core/crypto.h"
51#include "lib/core/debug.h"
52#include "lib/core/ife.h"
53#include "lib/core/protodefs.h"
54#include "lib/core/straddr.h"
55#include "lib/tool/pk.h"
56#include "hidb.h"
57#include "cert.h"
58
59
60/****************************************************************************
61 *
62 * SPKI
63 *
64 ***************************************************************************/
65
66/**
67 * Function that signs the cert sequence and creates the public key
68 * sequence and the signature sequence
69 *
70 * @param msg points to the msg gotten from "client" that should
71 * contain HIP_PARAM_CERT_SPKI_INFO
72 *
73 * @return 0 if signature was created without errors, negative value
74 * is returned on errors
75 */
76int hip_cert_spki_sign(struct hip_common *msg)
77{
78 int err = 0, sig_len = 0, algo = 0, t = 0;
79 const struct hip_cert_spki_info *p_cert;
80 struct hip_cert_spki_info *cert;
81 struct hip_host_id *host_id = NULL;
82 unsigned char sha_digest[SHA_DIGEST_LENGTH];
83 unsigned char *signature_b64 = NULL;
84 unsigned char *digest_b64 = NULL;
85 unsigned char *sha_retval;
86 uint8_t *signature = NULL;
87 DSA_SIG *dsa_sig = NULL;
88
89 /* RSA needed variables */
90 RSA *rsa = NULL;
91 unsigned char *e_bin = NULL, *n_bin = NULL, *n_b64 = NULL;
92 char *e_hex = NULL;
93
94 /* DSA needed variables */
95 DSA *dsa = NULL;
96 unsigned char *p_bin = NULL, *q_bin = NULL, *g_bin = NULL, *y_bin = NULL;
97 unsigned char *p_b64 = NULL, *q_b64 = NULL, *g_b64 = NULL, *y_b64 = NULL;
98
99 HIP_IFEL(!(cert = calloc(1, sizeof(struct hip_cert_spki_info))),
100 -1, "calloc for cert failed\n");
101 HIP_IFEL(!(p_cert = hip_get_param(msg, HIP_PARAM_CERT_SPKI_INFO)),
102 -1, "No cert_info struct found\n");
103 memcpy(cert, p_cert, sizeof(struct hip_cert_spki_info));
104
105 HIP_DEBUG_HIT("Getting keys for HIT", &cert->issuer_hit);
106
107 HIP_IFEL(hip_get_host_id_and_priv_key(&cert->issuer_hit,
108 HIP_ANY_ALGO,
109 &host_id,
110 (void **) &rsa),
111 -1, "Private key not found\n");
112
113 algo = host_id->rdata.algorithm;
114 if (algo == HIP_HI_DSA) {
115 dsa = (DSA *) rsa;
116 }
117
118 // Note: EVP_EncodeBlock(unsigned char *t, const unsigned char *f, int dlen) (vintage SSLeay
119 // code) is used to generate the different BASE64 representations. It requires an area of
120 // ((dlen + 2) / 3 * 4 + 1) bytes - so, obviously larger than the size of the input - to be
121 // available for its output (at location "t") - you have been warned.
122 digest_b64 = calloc(1, (SHA_DIGEST_LENGTH + 2) / 3 * 4 + 1);
123 HIP_IFEL(!digest_b64, -1, "calloc for digest_b64 failed\n");
124
125 /* build sha1 digest that will be signed */
126 HIP_IFEL(!(sha_retval = SHA1((unsigned char *) cert->cert, strlen(cert->cert), sha_digest)),
127 -1, "SHA1 error when creating digest.\n");
128
129 switch (algo) {
130 case HIP_HI_RSA:
131 sig_len = RSA_size(rsa);
132
133 signature = calloc(1, sig_len);
134 HIP_IFEL(!signature, -1, "calloc for signature failed\n");
135
136 signature_b64 = calloc(1, (sig_len + 2) / 3 * 4 + 1);
137 HIP_IFEL(!signature_b64, -1, "calloc for signature_b64 failed\n");
138
139 n_bin = calloc(1, BN_num_bytes(rsa->n));
140 HIP_IFEL(!n_bin, -1, "calloc for n_bin failed\n");
141
142 n_b64 = calloc(1, (BN_num_bytes(rsa->n) + 2) / 3 * 4 + 1);
143 HIP_IFEL(!n_b64, -1, "calloc for n_b64 failed\n");
144
145 e_bin = calloc(1, BN_num_bytes(rsa->e));
146 HIP_IFEL(!e_bin, -1, "calloc for e_bin failed\n");
147
148 /* RSA sign the digest */
149 err = RSA_sign(NID_sha1, sha_digest, SHA_DIGEST_LENGTH, signature,
150 (unsigned int *) &sig_len, rsa);
151 HIP_IFEL((err = err == 0 ? -1 : 0), -1, "RSA_sign error\n");
152 break;
153 case HIP_HI_ECDSA:
154 HIP_DEBUG("CALL TO UNIMPLEMENTED ECDSA CASE\n");
155 HIP_OUT_ERR(-1, "Unknown algorithm\n");
156 break;
157 case HIP_HI_DSA:
158 p_bin = malloc(BN_num_bytes(dsa->p) + 1);
159 HIP_IFEL(!p_bin, -1, "Malloc for p_bin failed\n");
160
161 q_bin = malloc(BN_num_bytes(dsa->q) + 1);
162 HIP_IFEL(!q_bin, -1, "Malloc for q_bin failed\n");
163
164 g_bin = malloc(BN_num_bytes(dsa->g) + 1);
165 HIP_IFEL(!g_bin, -1, "Malloc for g_bin failed\n");
166
167 y_bin = malloc(BN_num_bytes(dsa->pub_key) + 1);
168 HIP_IFEL(!y_bin, -1, "Malloc for y_bin failed\n");
169
170 p_b64 = malloc(BN_num_bytes(dsa->p) + 20);
171 HIP_IFEL(!p_b64, -1, "Malloc for p_b64 failed\n");
172
173 q_b64 = malloc(BN_num_bytes(dsa->q) + 20);
174 HIP_IFEL(!q_b64, -1, "Malloc for q_b64 failed\n");
175
176 g_b64 = malloc(BN_num_bytes(dsa->g) + 20);
177 HIP_IFEL(!g_b64, -1, "Malloc for g_b64 failed\n");
178
179 y_b64 = malloc(BN_num_bytes(dsa->pub_key) + 20);
180 HIP_IFEL(!y_b64, -1, "Malloc for y_b64 failed\n");
181
182#define HIP_DSA_SIG_SIZE 41 /* T(1) + R(20) + S(20) from RFC 2536 */
183 signature = calloc(1, HIP_DSA_SIG_SIZE);
184
185 t = BN_num_bytes(dsa->p);
186 t = (t - 64) / 8;
187 HIP_IFEL(t > 8, 1, "Illegal DSA key\n");
188
189 signature[0] = t;
190 dsa_sig = DSA_do_sign(sha_digest, SHA_DIGEST_LENGTH, dsa);
191 bn2bin_safe(dsa_sig->r, &signature[1], DSA_PRIV);
192 bn2bin_safe(dsa_sig->s, &signature[1 + DSA_PRIV], DSA_PRIV);
193 sig_len = SHA_DIGEST_LENGTH + DSA_PRIV * 2;
194 break;
195 default:
196 HIP_OUT_ERR(-1, "Unknown algorithm for signing\n");
197 }
198
199 HIP_IFEL(!EVP_EncodeBlock(digest_b64, sha_digest, SHA_DIGEST_LENGTH),
200 -1, "Failed to encode digest_b64\n");
201 HIP_IFEL(!EVP_EncodeBlock(signature_b64, signature, sig_len),
202 -1, "Failed to encode signature_b64\n");
203
204 /* create (signature (hash sha1 |digest|)|signature|) */
205 sprintf(cert->signature, "(signature (hash sha1 |%s|)|%s|)",
206 digest_b64, signature_b64);
207
208 /* Create the public key sequence */
209 switch (algo) {
210 case HIP_HI_RSA:
211 /*
212 * RSA public-key
213 * draft-paajarvi-xml-spki-cert-00 section 3.1.1
214 *
215 * <!ELEMENT rsa-pubkey (rsa-e,rsa-n)>
216 * <!ELEMENT rsa-e (#PCDATA)>
217 * <!ELEMENT rsa-n (#PCDATA)>
218 */
219 HIP_IFEL(!BN_bn2bin(rsa->n, n_bin),
220 -1,
221 "Error in converting public exponent from BN to bin\n");
222
223 HIP_IFEL(!EVP_EncodeBlock(n_b64, n_bin, BN_num_bytes(rsa->n)),
224 -1,
225 "Failed to encode n_b64\n");
226
227 HIP_IFEL(!BN_bn2bin(rsa->e, e_bin),
228 -1,
229 "Error in converting public exponent from BN to bin\n");
230
231 e_hex = BN_bn2hex(rsa->e);
232
233 sprintf(cert->public_key, "(public_key (rsa-pkcs1-sha1 (e #%s#)(n |%s|)))",
234 e_hex,
235 n_b64);
236 break;
237 case HIP_HI_ECDSA:
238 HIP_DEBUG("CALL TO UNIMPLEMENTED ECDSA CASE\n");
239 HIP_OUT_ERR(-1, "Unknown algorithm for signing\n");
240 break;
241 case HIP_HI_DSA:
242 /*
243 * DSA public-key
244 * draft-paajarvi-xml-spki-cert-00 section 3.1.2
245 *
246 * <!ELEMENT dsa-pubkey (dsa-p,dsa-q,dsa-g,dsa-y)>
247 * <!ELEMENT dsa-p (#PCDATA)>
248 * <!ELEMENT dsa-q (#PCDATA)>
249 * <!ELEMENT dsa-g (#PCDATA)>
250 * <!ELEMENT dsa-y (#PCDATA)>
251 */
252 HIP_IFEL(!BN_bn2bin(dsa->p, p_bin), -1,
253 "Error in converting public exponent from BN to bin\n");
254 HIP_IFEL(!EVP_EncodeBlock(p_b64, p_bin, BN_num_bytes(dsa->p)),
255 -1, "Failed to encode p_b64\n");
256
257 HIP_IFEL(!BN_bn2bin(dsa->q, q_bin), -1,
258 "Error in converting public exponent from BN to bin\n");
259 HIP_IFEL(!EVP_EncodeBlock(q_b64, q_bin, BN_num_bytes(dsa->q)),
260 -1, "Failed to encode q_64");
261
262 HIP_IFEL(!(BN_bn2bin(dsa->g, g_bin)), -1,
263 "Error in converting public exponent from BN to bin\n");
264 HIP_IFEL(!EVP_EncodeBlock(g_b64, g_bin, BN_num_bytes(dsa->g)),
265 -1, "Failed to encode g_b64\n");
266
267 HIP_IFEL(!BN_bn2bin(dsa->pub_key, y_bin), -1,
268 "Error in converting public exponent from BN to bin\n");
269 HIP_IFEL(!EVP_EncodeBlock(y_b64, y_bin, BN_num_bytes(dsa->pub_key)),
270 -1, "Failed to encode y_b64\n");
271
272 sprintf(cert->public_key, "(public_key (dsa-pkcs1-sha1 (p |%s|)(q |%s|)"
273 "(g |%s|)(y |%s|)))",
274 p_b64, q_b64, g_b64, y_b64);
275 break;
276 default:
277 HIP_OUT_ERR(-1, "Unknown algorithm for public-key element\n");
278 }
279
280 /* Put the results into the msg back */
281 hip_msg_init(msg);
282
283 HIP_IFEL(hip_build_user_hdr(msg, HIP_MSG_CERT_SPKI_SIGN, 0), -1,
284 "Failed to build user header\n");
285 HIP_IFEL(hip_build_param_cert_spki_info(msg, cert), -1,
286 "Failed to build cert_info\n");
287
288out_err:
289
290 /* free malloced memory */
291 free(digest_b64);
292 free(signature_b64);
293 free(signature);
294 free(host_id);
295
296 /* RSA pubkey */
297 free(e_bin);
298 free(n_bin);
299 /* encoded */
300 OPENSSL_free(e_hex);
301 free(n_b64);
302
303 /* DSA pubkey */
304 free(p_bin);
305 free(q_bin);
306 free(g_bin);
307 free(y_bin);
308 /* encoded */
309 free(p_b64);
310 free(q_b64);
311 free(g_b64);
312 free(y_b64);
313
314 DSA_SIG_free(dsa_sig);
315
316 free(cert);
317
318 return err;
319}
320
321/**
322 * Function that verifies the signature in the given SPKI cert sent by
323 * the "client"
324 *
325 * @param msg points to the msg gotten from "client" that contains a
326 * spki cert in CERT parameter
327 *
328 * @return 0 if signature matches, -1 if error or signature did NOT match
329 */
330int hip_cert_spki_verify(struct hip_common *msg)
331{
332 int err = 0, start = 0, stop = 0, evpret = 0, keylen = 0, algo = 0;
333 char buf[200];
334
335 unsigned char sha_digest[21];
336 unsigned char *sha_retval;
337 unsigned char *signature_hash = NULL;
338 unsigned char *signature_hash_b64 = NULL;
339 unsigned char *signature_b64 = NULL;
340
341 const struct hip_cert_spki_info *p_cert;
342 struct hip_cert_spki_info *cert = NULL;
343 unsigned char *signature = NULL;
344
345 /** RSA */
346 RSA *rsa = NULL;
347 unsigned long e_code;
348 char *e_hex = NULL;
349 unsigned char *modulus_b64 = NULL;
350 unsigned char *modulus = NULL;
351
352 /** DSA */
353 DSA *dsa = NULL;
354 unsigned char *p_bin = NULL, *q_bin = NULL, *g_bin = NULL, *y_bin = NULL;
355 unsigned char *p_b64 = NULL, *q_b64 = NULL, *g_b64 = NULL, *y_b64 = NULL;
356 DSA_SIG *dsa_sig = NULL;
357
358 /* rules for regular expressions */
359
360 /*
361 * Rule to get the info if we are using DSA
362 */
363 char dsa_rule[] = "[d][s][a][-][p][k][c][s][1][-][s][h][a][1]";
364
365 /*
366 * Rule to get the info if we are using RSA
367 */
368 char rsa_rule[] = "[r][s][a][-][p][k][c][s][1][-][s][h][a][1]";
369
370 /*
371 * Rule to get DSA p
372 * Look for pattern "(p |" and stop when first "|"
373 * anything in base 64 is accepted inbetween
374 */
375 char p_rule[] = "[(][p][ ][|][[A-Za-z0-9+/()#=-]*[|]";
376
377 /*
378 * Rule to get DSA q
379 * Look for pattern "(q |" and stop when first "|"
380 * anything in base 64 is accepted inbetween
381 */
382 char q_rule[] = "[(][q][ ][|][[A-Za-z0-9+/()#=-]*[|]";
383
384 /*
385 * Rule to get DSA g
386 * Look for pattern "(g |" and stop when first "|"
387 * anything in base 64 is accepted inbetween
388 */
389 char g_rule[] = "[(][g][ ][|][[A-Za-z0-9+/()#=-]*[|]";
390
391 /*
392 * Rule to get DSA y / pub_key
393 * Look for pattern "(y |" and stop when first "|"
394 * anything in base 64 is accepted inbetween
395 */
396 char y_rule[] = "[(][y][ ][|][[A-Za-z0-9+/()#=-]*[|]";
397
398 /*
399 * rule to get the public exponent RSA
400 * Look for the part that says # and after that some hex blob and #
401 */
402 char e_rule[] = "[#][0-9A-Fa-f]*[#]";
403
404 /*
405 * rule to get the public modulus RSA
406 * Look for the part that starts with '|' and after that anything
407 * that is in base 64 char set and then '|' again
408 */
409 char n_rule[] = "[|][A-Za-z0-9+/()#=-]*[|]";
410
411 /*
412 * rule to get the signature hash
413 * Look for the similar than the n_rule
414 */
415 char h_rule[] = "[|][A-Za-z0-9+/()#=-]*[|]";
416
417 /*
418 * rule to get the signature
419 * Look for part that starts ")|" and base 64 blob after it
420 * and stops to '|' char remember to add and subtract 2 from
421 * the indexes below
422 */
423 char s_rule[] = "[)][|][A-Za-z0-9+/()#=-]*[|]";
424
425 cert = calloc(1, sizeof(struct hip_cert_spki_info));
426 HIP_IFEL(!cert, -1, "calloc for cert failed\n");
427
428 HIP_IFEL(!(p_cert = hip_get_param(msg, HIP_PARAM_CERT_SPKI_INFO)),
429 -1, "No cert_info struct found\n");
430 memcpy(cert, p_cert, sizeof(struct hip_cert_spki_info));
431
432 /* check the algo DSA or RSA */
433 HIP_DEBUG("Verifying\nRunning regexps to identify algo\n");
434 start = stop = 0;
435 algo = hip_cert_regex(dsa_rule, cert->public_key, &start, &stop);
436 if (algo != -1) {
437 HIP_DEBUG("Public-key is DSA\n");
438 algo = HIP_HI_DSA;
439 goto algo_check_done;
440 }
441 start = stop = 0;
442 algo = hip_cert_regex(rsa_rule, cert->public_key, &start, &stop);
443 if (algo != -1) {
444 HIP_DEBUG("Public-key is RSA\n");
445 algo = HIP_HI_RSA;
446 goto algo_check_done;
447 }
448
449algo_check_done:
450 switch (algo) {
451 case HIP_HI_RSA:
452 /* malloc space for new rsa */
453 rsa = RSA_new();
454 HIP_IFEL(!rsa, -1, "Failed to malloc RSA\n");
455
456 /* extract the public-key from cert to rsa */
457
458 /* public exponent first */
459 start = stop = 0;
460 HIP_IFEL(hip_cert_regex(e_rule, cert->public_key, &start, &stop), -1,
461 "Failed to run hip_cert_regex (exponent)\n");
462 e_hex = malloc(stop - start);
463 HIP_IFEL(!e_hex, -1, "Malloc for e_hex failed\n");
464 snprintf(e_hex, stop - start - 1, "%s", &cert->public_key[start + 1]);
465
466 /* public modulus */
467 start = stop = 0;
468 HIP_IFEL(hip_cert_regex(n_rule, cert->public_key, &start, &stop), -1,
469 "Failed to run hip_cert_regex (modulus)\n");
470 modulus_b64 = calloc(1, stop - start + 1);
471 HIP_IFEL(!modulus_b64, -1, "calloc for modulus_b64 failed\n");
472 modulus = calloc(1, stop - start + 1);
473 HIP_IFEL(!modulus, -1, "calloc for modulus failed\n");
474 snprintf((char *) modulus_b64, stop - start - 1, "%s",
475 &cert->public_key[start + 1]);
476
477 /* put the stuff into the RSA struct */
478 BN_hex2bn(&rsa->e, e_hex);
479 evpret = EVP_DecodeBlock(modulus, modulus_b64,
480 strlen((char *) modulus_b64));
481
482 /* EVP returns a multiple of 3 octets, subtract any extra */
483 keylen = evpret;
484 if (keylen % 4 != 0) {
485 --keylen;
486 keylen = keylen - keylen % 2;
487 }
488 signature = malloc(keylen);
489 HIP_IFEL(!signature, -1, "Malloc for signature failed.\n");
490 rsa->n = BN_bin2bn(modulus, keylen, 0);
491 break;
492 case HIP_HI_DSA:
493 /* malloc space for new dsa */
494 dsa = DSA_new();
495 HIP_IFEL(!dsa, -1, "Failed to malloc DSA\n");
496
497 /* Extract public key from the cert */
498
499 /* dsa->p */
500 start = stop = 0;
501 HIP_IFEL(hip_cert_regex(p_rule, cert->public_key, &start, &stop), -1,
502 "Failed to run hip_cert_regex dsa->p\n");
503 p_b64 = calloc(1, stop - start + 1);
504 HIP_IFEL(!p_b64, -1, "calloc for p_b64 failed\n");
505 p_bin = calloc(1, stop - start + 1);
506 HIP_IFEL(!p_bin, -1, "calloc for p_bin failed\n");
507 snprintf((char *) p_b64, stop - start - 1, "%s",
508 &cert->public_key[start + 1]);
509 evpret = EVP_DecodeBlock(p_bin, p_b64, strlen((char *) p_b64));
510
511 /* dsa->q */
512 start = stop = 0;
513 HIP_IFEL(hip_cert_regex(q_rule, cert->public_key, &start, &stop), -1,
514 "Failed to run hip_cert_regex dsa->q\n");
515 q_b64 = calloc(1, stop - start + 1);
516 HIP_IFEL(!q_b64, -1, "calloc for q_b64 failed\n");
517 q_bin = calloc(1, stop - start + 1);
518 HIP_IFEL(!q_bin, -1, "calloc for q_bin failed\n");
519 snprintf((char *) q_b64, stop - start - 1, "%s",
520 &cert->public_key[start + 1]);
521 evpret = EVP_DecodeBlock(q_bin, q_b64, strlen((char *) q_b64));
522
523 /* dsa->g */
524 start = stop = 0;
525 HIP_IFEL(hip_cert_regex(g_rule, cert->public_key, &start, &stop), -1,
526 "Failed to run hip_cert_regex dsa->g\n");
527 g_b64 = calloc(1, stop - start + 1);
528 HIP_IFEL(!g_b64, -1, "calloc for g_b64 failed\n");
529 g_bin = calloc(1, stop - start + 1);
530 HIP_IFEL(!g_bin, -1, "calloc for g_bin failed\n");
531 snprintf((char *) g_b64, stop - start - 1, "%s",
532 &cert->public_key[start + 1]);
533 evpret = EVP_DecodeBlock(g_bin, g_b64, strlen((char *) g_b64));
534
535 /* dsa->y */
536 start = stop = 0;
537 HIP_IFEL(hip_cert_regex(y_rule, cert->public_key, &start, &stop), -1,
538 "Failed to run hip_cert_regex dsa->y\n");
539 y_b64 = calloc(1, stop - start + 1);
540 HIP_IFEL(!y_b64, -1, "calloc for y_b64 failed\n");
541 y_bin = calloc(1, stop - start + 1);
542 HIP_IFEL(!y_bin, -1, "calloc for y_bin failed\n");
543 snprintf((char *) y_b64, stop - start - 1, "%s",
544 &cert->public_key[start + 1]);
545 evpret = EVP_DecodeBlock(y_bin, y_b64, strlen((char *) y_b64));
546 break;
547 case HIP_HI_ECDSA:
548 HIP_DEBUG("CALL TO UNIMPLEMENTED ECDSA CASE\n");
549 HIP_OUT_ERR(-1, "Unknown algorithm\n");
550 break;
551 default:
552 HIP_OUT_ERR(-1, "Unknown algorithm\n");
553 }
554
555 /* build sha1 digest that will be signed */
556 HIP_IFEL(!(sha_retval = SHA1((unsigned char *) cert->cert,
557 strlen(cert->cert), sha_digest)),
558 -1, "SHA1 error when creating digest.\n");
559
560 /* Get the signature hash and compare it to the sha_digest we just made */
561 start = stop = 0;
562 HIP_IFEL(hip_cert_regex(h_rule, cert->signature, &start, &stop), -1,
563 "Failed to run hip_cert_regex (signature hash)\n");
564 signature_hash_b64 = calloc(1, stop - start + 1);
565 HIP_IFEL(!signature_hash_b64, -1, "Failed to calloc signature_hash_b64\n");
566 signature_hash = malloc(stop - start + 1);
567 HIP_IFEL(!signature_hash, -1, "Failed to malloc signature_hash\n");
568 snprintf((char *) signature_hash_b64, stop - start - 1, "%s",
569 &cert->signature[start + 1]);
570 evpret = EVP_DecodeBlock(signature_hash, signature_hash_b64,
571 strlen((char *) signature_hash_b64));
572 HIP_IFEL(memcmp(sha_digest, signature_hash, 20), -1,
573 "Signature hash did not match of the one made from the"
574 "cert sequence in the certificate\n");
575
576 /* memset signature and put it into its place */
577 start = stop = 0;
578 HIP_IFEL(hip_cert_regex(s_rule, cert->signature, &start, &stop), -1,
579 "Failed to run hip_cert_regex (signature)\n");
580 signature_b64 = calloc(1, stop - start + 1);
581 HIP_IFEL(!signature_b64, -1, "Failed to calloc signature_b64\n");
582 snprintf((char *) signature_b64, stop - start - 2, "%s",
583 &cert->signature[start + 2]);
584 if (algo == HIP_HI_DSA) {
585 signature = malloc(stop - start + 1);
586 HIP_IFEL(!signature, -1, "Failed to malloc signature (dsa)\n");
587 }
588 evpret = EVP_DecodeBlock(signature, signature_b64,
589 strlen((char *) signature_b64));
590
591 switch (algo) {
592 case HIP_HI_RSA:
593 /* do the verification */
594 err = RSA_verify(NID_sha1, sha_digest, SHA_DIGEST_LENGTH,
595 signature, RSA_size(rsa), rsa);
596 e_code = ERR_get_error();
597 ERR_load_crypto_strings();
598 ERR_error_string(e_code, buf);
599
600 /* RSA_verify returns 1 if success. */
601 cert->success = err == 1 ? 0 : -1;
602 HIP_IFEL((err = err == 1 ? 0 : -1), -1, "RSA_verify error\n");
603 break;
604 case HIP_HI_DSA:
605 /* build the signature structure */
606 dsa_sig = DSA_SIG_new();
607 HIP_IFEL(!dsa_sig, 1, "Failed to allocate DSA_SIG\n");
608 dsa_sig->r = BN_bin2bn(&signature[1], DSA_PRIV, NULL);
609 dsa_sig->s = BN_bin2bn(&signature[1 + DSA_PRIV], DSA_PRIV, NULL);
610
611 /* verify the DSA signature */
612 err = DSA_do_verify(sha_digest, SHA_DIGEST_LENGTH,
613 dsa_sig, dsa) == 0 ? 1 : 0;
614
615 /* DSA_do_verify returns 1 if success. */
616 cert->success = err == 1 ? 0 : -1;
617 HIP_IFEL((err = err == 1 ? 0 : -1), -1, "DSA_do_verify error\n");
618 break;
619 case HIP_HI_ECDSA:
620 HIP_DEBUG("CALL TO UNIMPLEMENTED ECDSA CASE\n");
621 HIP_OUT_ERR(-1, "Unknown algorithm for signing\n");
622 break;
623 default:
624 HIP_OUT_ERR(-1, "Unknown algorithm\n");
625 }
626
627 hip_msg_init(msg);
628
629 HIP_IFEL(hip_build_user_hdr(msg, HIP_MSG_CERT_SPKI_SIGN, 0), -1,
630 "Failed to build user header\n");
631 HIP_IFEL(hip_build_param_cert_spki_info(msg, cert), -1,
632 "Failed to build cert_info\n");
633
634out_err:
635 free(signature_hash_b64);
636 free(signature_hash);
637 free(modulus_b64);
638 free(modulus);
639 free(cert);
640 free(signature);
641 free(e_hex);
642 RSA_free(rsa);
643 DSA_free(dsa);
644 DSA_SIG_free(dsa_sig);
645
646 return err;
647}
648
649/****************************************************************************
650 *
651 * X.509v3
652 *
653 ***************************************************************************/
654
655/**
656 * Function that creates the certificate and sends it to back to the client.
657 *
658 * @param msg is a pointer to the msg containing a x509v3 cert in cert parameter
659 *
660 * @return 0 on success negative otherwise.
661 */
662int hip_cert_x509v3_handle_request_to_sign(struct hip_common *msg)
663{
664 int err = 0, i = 0, nid = 0, ret = 0, secs = 0, algo = 0;
665 CONF *conf;
666 CONF_VALUE *item;
667 STACK_OF(CONF_VALUE) *sec_general = NULL;
668 STACK_OF(CONF_VALUE) *sec_name = NULL;
669 STACK_OF(CONF_VALUE) *sec_ext = NULL;
670
671 X509_REQ *req = NULL;
672 X509_NAME *issuer = NULL;
673 X509_NAME *subj = NULL;
674 X509_EXTENSION *ext = NULL;
675 STACK_OF(X509_EXTENSION) *extlist = NULL;
676 X509_NAME_ENTRY *ent;
677 EVP_PKEY *pkey;
678 /** XX TODO THIS should come from a configuration file
679 * monotonically increasing counter */
680 long serial = 0;
681 const EVP_MD *digest = NULL;
682 X509 *cert;
683 X509V3_CTX ctx;
684 const struct hip_cert_x509_req *subject;
685 char subject_hit[41];
686 char issuer_hit[41];
687 char ialtname[45];
688 char saltname[45];
689 struct in6_addr *issuer_hit_n;
690 struct hip_host_id *host_id;
691 RSA *rsa = NULL;
692 DSA *dsa = NULL;
693 unsigned char *der_cert = NULL;
694 int der_cert_len = 0;
695 char arg1[21];
696 char arg2[21];
697
698 HIP_IFEL(!(issuer_hit_n = malloc(sizeof(struct in6_addr))), -1,
699 "Malloc for subject failed\n");
700 HIP_IFEL(!(pkey = malloc(sizeof(EVP_PKEY))), -1,
701 "Malloc for pkey failed\n");
702
703 OpenSSL_add_all_algorithms();
704 ERR_load_crypto_strings();
705
706 HIP_DEBUG("Reading configuration file (%s)\n", HIP_CERT_CONF_PATH);
707 conf = hip_open_conf(HIP_CERT_CONF_PATH);
708 sec_general = hip_read_conf_section("hip_x509v3", conf);
709 sec_name = hip_read_conf_section("hip_x509v3_name", conf);
710 sec_ext = hip_read_conf_section("hip_x509v3_extensions", conf);
711 NCONF_free(conf);
712
713 /* Get the general information */
714 HIP_IFEL(sec_general == NULL, -1,
715 "Failed to load general certificate information\n");
716 HIP_IFEL(!(req = X509_REQ_new()), -1, "Failed to create X509_REQ object");
717
718 HIP_IFEL(sec_name == NULL, -1,
719 "Failed to load issuer naming information for the certificate\n");
720
721 /* Issuer naming */
722 if (sec_general != NULL) {
723 /* Loop through the conf stack for general information */
724 extlist = sk_X509_EXTENSION_new_null();
725 for (i = 0; i < sk_CONF_VALUE_num(sec_general); i++) {
726 item = sk_CONF_VALUE_value(sec_general, i);
727 if (!strcmp(item->name, "issuerhit")) {
728 strcpy(issuer_hit, item->value);
729 ret = inet_pton(AF_INET6, item->value, issuer_hit_n);
730 HIP_IFEL(ret < 0 && errno == EAFNOSUPPORT, -1,
731 "Failed to convert issuer HIT to hip_hit_t\n");
732 HIP_DEBUG_HIT("Issuer HIT", issuer_hit_n);
733 HIP_IFEL(!inet_ntop(AF_INET6, issuer_hit_n,
734 issuer_hit, sizeof(issuer_hit)),
735 -1, "Failed to convert subject hit to "
736 "presentation format\n");
737 }
738 if (!strcmp(item->name, "days")) {
739 secs = HIP_CERT_DAY * atoi(item->value);
740 }
741 }
742 }
743 HIP_IFEL(!(issuer = X509_NAME_new()), -1, "Failed to set create issuer name");
744 nid = OBJ_txt2nid("commonName");
745 HIP_IFEL(nid == NID_undef, -1, "NID text not defined\n");
746 HIP_IFEL(!(ent = X509_NAME_ENTRY_create_by_NID(NULL, nid, MBSTRING_ASC,
747 (unsigned char *) issuer_hit, -1)), -1,
748 "Failed to create name entry for issuer\n");
749 HIP_IFEL(X509_NAME_add_entry(issuer, ent, -1, 0) != 1, -1,
750 "Failed to add entry to issuer name\n");
751
752 /* Subject naming */
753 /* Get the subject hit from msg */
754 HIP_IFEL(!(subject = hip_get_param(msg, HIP_PARAM_CERT_X509_REQ)),
755 -1, "No cert_info struct found\n");
756 HIP_IFEL(!inet_ntop(AF_INET6, &subject->addr, subject_hit, sizeof(subject_hit)),
757 -1, "Failed to convert subject hit to presentation format\n");
758 HIP_IFEL(!(subj = X509_NAME_new()), -1, "Failed to set create subject name");
759 nid = OBJ_txt2nid("commonName");
760 HIP_IFEL(nid == NID_undef, -1, "NID text not defined\n");
761 HIP_IFEL(!(ent = X509_NAME_ENTRY_create_by_NID(NULL, nid, MBSTRING_ASC,
762 (unsigned char *) subject_hit, -1)), -1,
763 "Failed to create name entry for subject\n");
764 HIP_IFEL(X509_NAME_add_entry(subj, ent, -1, 0) != 1, -1,
765 "Failed to add entry to subject name\n");
766 HIP_IFEL(X509_REQ_set_subject_name(req, subj) != 1, -1,
767 "Failed to add subject name to certificate request\n");
768
769 /* XX TODO add a check to skip subjectAltName and issuerAltName because they are
770 * already in use by with IP:<hit> stuff */
771 if (sec_ext != NULL) {
772 /* Loop through the conf stack and add extensions to ext stack */
773 extlist = sk_X509_EXTENSION_new_null();
774 for (i = 0; i < sk_CONF_VALUE_num(sec_ext); i++) {
775 item = sk_CONF_VALUE_value(sec_ext, i);
776 HIP_IFEL(!(ext = X509V3_EXT_conf(NULL, &ctx,
777 item->name, item->value)), -1,
778 "Failed to create extension\n");
779 sk_X509_EXTENSION_push(extlist, ext);
780 }
781 HIP_IFEL(!X509_REQ_add_extensions(req, extlist), -1,
782 "Failed to add extensions to the request\n");
783 }
784
785 /** NOW WE ARE READY TO CREATE A CERTIFICATE FROM THE REQUEST */
786 HIP_DEBUG("Starting the certificate creation\n");
787
788 HIP_IFEL(!(cert = X509_new()), -1,
789 "Failed to create X509 object\n");
790
791 HIP_IFEL(X509_set_version(cert, 2L) != 1, -1,
792 "Failed to set certificate version\n");
793 /** XX TODO serial should be stored after increasing it */
794 ASN1_INTEGER_set(X509_get_serialNumber(cert), serial++);
795
796 HIP_IFEL(X509_set_subject_name(cert, subj) != 1, -1,
797 "Failed to set subject name of certificate\n");
798 HIP_IFEL(X509_set_issuer_name(cert, issuer) != 1, -1,
799 "Failed to set issuer name of certificate\n");
800 HIP_IFEL(!X509_gmtime_adj(X509_get_notBefore(cert), 0), -1,
801 "Error setting beginning time of the certificate");
802 HIP_IFEL(!X509_gmtime_adj(X509_get_notAfter(cert), secs), -1,
803 "Error setting ending time of the certificate");
804
805 HIP_DEBUG("Getting the key\n");
806
807 HIP_IFEL(hip_get_host_id_and_priv_key(issuer_hit_n,
808 HIP_ANY_ALGO,
809 &host_id,
810 (void *) &rsa),
811 -1, "Private key not found\n");
812
813 algo = host_id->rdata.algorithm;
814 if (algo == HIP_HI_DSA) {
815 dsa = (DSA *) rsa;
816 }
817
818 switch (algo) {
819 case HIP_HI_RSA:
820 HIP_IFEL(!EVP_PKEY_assign_RSA(pkey, rsa), -1,
821 "Failed to convert RSA to EVP_PKEY\n");
822 HIP_IFEL(X509_set_pubkey(cert, pkey) != 1, -1,
823 "Failed to set public key of the certificate\n");
824 break;
825 case HIP_HI_DSA:
826 HIP_IFEL(!EVP_PKEY_assign_DSA(pkey, dsa), -1,
827 "Failed to convert DSA to EVP_PKEY\n");
828 HIP_IFEL(X509_set_pubkey(cert, pkey) != 1, -1,
829 "Failed to set public key of the certificate\n");
830 break;
831 case HIP_HI_ECDSA:
832 HIP_DEBUG("CALL TO UNIMPLEMENTED ECDSA CASE\n");
833 HIP_OUT_ERR(-1, "Unknown algorithm for signing\n");
834 break;
835 default:
836 HIP_OUT_ERR(-1, "Unknown algorithm\n");
837 }
838
839 if (sec_ext != NULL) {
840 for (i = 0; i < sk_CONF_VALUE_num(sec_ext); i++) {
841 item = sk_CONF_VALUE_value(sec_ext, i);
842 /*
843 * Skip issuerAltName and subjectAltName because
844 * HITs use them already. Skip also basicConstraint =
845 * CA:true and subjectKeyIdentifier because they are
846 * added automatically in the code below
847 */
848 if (!strcmp(item->name, "issuerAltname")) {
849 continue;
850 }
851 if (!strcmp(item->name, "subjectAltname")) {
852 continue;
853 }
854 if (0 == memcmp(subject_hit, issuer_hit, sizeof(issuer_hit))) {
855 if (!strcmp(item->name, "basicConstraints") &&
856 !strcmp(item->value, "CA:true")) {
857 continue;
858 }
859 if (!strcmp(item->name, "subjectKeyIdentifier")) {
860 continue;
861 }
862 }
863 HIP_IFEL(!(ext = X509V3_EXT_conf(NULL, &ctx,
864 item->name, item->value)), -1,
865 "Failed to create extension\n");
866 HIP_IFEL(!X509_add_ext(cert, ext, -1), -1,
867 "Failed to add extensions to the cert\n");
868 }
869 }
870
871 if (0 == memcmp(subject_hit, issuer_hit, sizeof(issuer_hit))) {
872 /* Subjects and issuers hit match so
873 * we are writing a CA cert and in CA self-signed
874 * certificate you have to have subject key identifier
875 * present, when adding subjectKeyIdentifier give string
876 * hash to the X509_EXT_conf it knows what to do with it */
877
878 /* X509V3_EXT_conf() doesn't accept const char *, so we
879 * write the arguments to a buffer first */
880 sprintf(arg1, "basicConstraints");
881 sprintf(arg2, "CA:true");
882 HIP_IFEL(!(ext = X509V3_EXT_conf(NULL, &ctx,
883 arg1, arg2)), -1,
884 "Failed to create extension\n");
885 HIP_IFEL(!X509_add_ext(cert, ext, -1), -1,
886 "Failed to add extensions to the cert\n");
887
888 sprintf(arg1, "subjectKeyIdentifier");
889 sprintf(arg2, "hash");
890 HIP_IFEL(!(ext = X509V3_EXT_conf(NULL, &ctx,
891 arg1, arg2)), -1,
892 "Failed to create extension\n");
893 HIP_IFEL(!X509_add_ext(cert, ext, -1), -1,
894 "Failed to add extensions to the cert\n");
895 }
896
897 /* add subjectAltName = IP:<HIT> */
898 sprintf(arg1, "issuerAltName");
899 sprintf(ialtname, "IP:%s", issuer_hit);
900 HIP_IFEL(!(ext = X509V3_EXT_conf(NULL, &ctx,
901 arg1, ialtname)), -1,
902 "Failed to create extension\n");
903 HIP_IFEL(!X509_add_ext(cert, ext, -1), -1,
904 "Failed to add extensions to the cert\n");
905 /* add subjectAltName = IP:<HIT> */
906 sprintf(arg1, "subjectAltName");
907 sprintf(saltname, "IP:%s", subject_hit);
908 HIP_IFEL(!(ext = X509V3_EXT_conf(NULL, &ctx,
909 arg1, saltname)), -1,
910 "Failed to create extension\n");
911 HIP_IFEL(!X509_add_ext(cert, ext, -1), -1,
912 "Failed to add extensions to the cert\n");
913
914 switch (algo) {
915 case HIP_HI_RSA:
916 digest = EVP_sha1();
917 break;
918 case HIP_HI_DSA:
919 digest = EVP_dss1();
920 break;
921 case HIP_HI_ECDSA:
922 HIP_DEBUG("CALL TO UNIMPLEMENTED ECDSA CASE\n");
923 HIP_OUT_ERR(-1, "Unknown algorithm for signing\n");
924 break;
925 default:
926 HIP_OUT_ERR(-1, "Unknown algorithm\n");
927 }
928
929 HIP_IFEL(!X509_sign(cert, pkey, digest), -1,
930 "Failed to sign x509v3 certificate\n");
931
932 /** DER */
933 HIP_IFEL((der_cert_len = i2d_X509(cert, &der_cert)) < 0, -1,
934 "Failed to convert cert to DER\n");
935 /** end DER */
936
937 hip_msg_init(msg);
938
939 HIP_IFEL(hip_build_user_hdr(msg, HIP_MSG_CERT_X509V3_SIGN, 0), -1,
940 "Failed to build user header\n");
941 HIP_IFEL(hip_build_param_cert_x509_resp(msg, (char *) der_cert, der_cert_len), -1,
942 "Failed to create x509 response parameter\n");
943
944out_err:
945 free(host_id);
946 X509_REQ_free(req);
947 sk_X509_EXTENSION_pop_free(extlist, X509_EXTENSION_free);
948 return err;
949}
950
951static int verify_callback(int ok, DBG X509_STORE_CTX *stor)
952{
953 /* This is not called from anywhere else than this file */
954 if (!ok) {
955 HIP_DEBUG("Error: %s\n", X509_verify_cert_error_string(stor->error));
956 }
957 return ok;
958}
959
960/**
961 * Function verifies the given certificate and sends it to back to the client.
962 *
963 * @param msg is a pointer to the requesting msg that contains a cert parameter with x509v3 cert
964 *
965 * @return 0 on success negative otherwise.
966 */
967int hip_cert_x509v3_handle_request_to_verify(struct hip_common *msg)
968{
969 int err = 0;
970 struct hip_cert_x509_resp verify;
971 const struct hip_cert_x509_resp *p;
972 X509 *cert = NULL;
973 X509_STORE *store = NULL;
974 X509_STORE_CTX *verify_ctx = NULL;
975 unsigned char *der_cert = NULL;
976 const unsigned char *vessel;
977
978 OpenSSL_add_all_algorithms();
979 ERR_load_crypto_strings();
980
981 HIP_IFEL(!(p = hip_get_param(msg, HIP_PARAM_CERT_X509_REQ)), -1,
982 "Failed to get cert info from the msg\n");
983 memcpy(&verify, p, sizeof(struct hip_cert_x509_resp));
984
985 der_cert = (unsigned char *) &p->der;
986
987 vessel = p->der;
988 HIP_IFEL((cert = d2i_X509(NULL, &vessel, verify.der_len)) == NULL, -1,
989 "Failed to convert cert from DER to internal format\n");
990 /*
991 * HIP_IFEL(!X509_print_fp(stdout, cert), -1,
992 * "Failed to print x.509v3 in human readable format\n");
993 */
994
995 HIP_IFEL(!(store = X509_STORE_new()), -1,
996 "Failed to create X509_STORE_CTX object\n");
997 X509_STORE_set_verify_cb_func(store, verify_callback);
998
999 /* self signed so te cert itself should verify itself */
1000
1001 HIP_IFEL(!X509_STORE_add_cert(store, cert), -1,
1002 "Failed to add cert to ctx\n");
1003
1004 HIP_IFEL(!(verify_ctx = X509_STORE_CTX_new()), -1,
1005 "Failed to create X509_STORE_CTX object\n");
1006
1007 HIP_IFEL(X509_STORE_CTX_init(verify_ctx, store, cert, NULL) != 1, -1,
1008 "Failed to initialize verification context\n");
1009
1010 if (X509_verify_cert(verify_ctx) != 1) {
1011 HIP_DEBUG("Error verifying the certificate\n");
1012 err = -1;
1013 } else {
1014 HIP_DEBUG("Certificate verified correctly!\n");
1015 err = 0;
1016 }
1017
1018 hip_msg_init(msg);
1019 HIP_IFEL(hip_build_user_hdr(msg, HIP_MSG_CERT_X509V3_VERIFY, err), -1,
1020 "Failed to build user header\n");
1021 HIP_IFEL(hip_build_param_cert_x509_resp(msg, (char *) &der_cert, p->der_len), -1,
1022 "Failed to create x509 response parameter\n");
1023
1024out_err:
1025 X509_STORE_CTX_cleanup(verify_ctx);
1026 X509_STORE_free(store);
1027 X509_free(cert);
1028 return err;
1029}
10300
=== removed file 'hipd/cert.h'
--- hipd/cert.h 2011-11-25 17:56:24 +0000
+++ hipd/cert.h 1970-01-01 00:00:00 +0000
@@ -1,48 +0,0 @@
1/*
2 * Copyright (c) 2010 Aalto University and RWTH Aachen University.
3 *
4 * Permission is hereby granted, free of charge, to any person
5 * obtaining a copy of this software and associated documentation
6 * files (the "Software"), to deal in the Software without
7 * restriction, including without limitation the rights to use,
8 * copy, modify, merge, publish, distribute, sublicense, and/or sell
9 * copies of the Software, and to permit persons to whom the
10 * Software is furnished to do so, subject to the following
11 * conditions:
12 *
13 * The above copyright notice and this permission notice shall be
14 * included in all copies or substantial portions of the Software.
15 *
16 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
17 * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
18 * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
19 * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
20 * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
21 * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
22 * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
23 * OTHER DEALINGS IN THE SOFTWARE.
24 */
25
26/**
27 * @file
28 *
29 * Certificate signing and verification functions.
30 */
31
32#ifndef HIPL_HIPD_CERT_H
33#define HIPL_HIPD_CERT_H
34
35#include <openssl/rsa.h>
36
37#include "lib/core/hashtable.h"
38#include "lib/core/protodefs.h"
39
40/** SPKI */
41int hip_cert_spki_sign(struct hip_common *);
42int hip_cert_spki_verify(struct hip_common *);
43
44/** x509v3 */
45int hip_cert_x509v3_handle_request_to_sign(struct hip_common *);
46int hip_cert_x509v3_handle_request_to_verify(struct hip_common *);
47
48#endif /* HIPL_HIPD_CERT_H */
490
=== modified file 'hipd/init.c'
--- hipd/init.c 2012-01-18 21:21:26 +0000
+++ hipd/init.c 2012-02-20 21:55:24 +0000
@@ -435,81 +435,6 @@
435 return err;435 return err;
436}436}
437437
438/* Needed if the configuration file for certs did not exist */
439#define HIP_CERT_INIT_DAYS 10
440
441/**
442 * Initialize certificates for the local host
443 *
444 * @return zero on success or negative on failure
445 */
446static int init_certs(void)
447{
448 int err = 0;
449 char hit[41];
450 FILE *conf_file;
451 struct local_host_id *entry;
452 char hostname[HIP_HOST_ID_HOSTNAME_LEN_MAX];
453
454 HIP_IFEL(gethostname(hostname, sizeof(hostname)), -1,
455 "gethostname failed\n");
456
457 conf_file = fopen(HIP_CERT_CONF_PATH, "r");
458 if (!conf_file) {
459 HIP_DEBUG("Configuration file did NOT exist creating it and "
460 "filling it with default information\n");
461 /* Fetch the first RSA HIT */
462 entry = hip_get_hostid_entry_by_lhi_and_algo(NULL, HIP_HI_RSA, -1);
463 if (entry == NULL) {
464 HIP_DEBUG("Failed to get the first RSA HI");
465 goto out_err;
466 }
467 hip_in6_ntop(&entry->hit, hit);
468 conf_file = fopen(HIP_CERT_CONF_PATH, "w+");
469 fprintf(conf_file,
470 "# Section containing SPKI related information\n"
471 "#\n"
472 "# issuerhit = what hit is to be used when signing\n"
473 "# days = how long is this key valid\n"
474 "\n"
475 "[ hip_spki ]\n"
476 "issuerhit = %s\n"
477 "days = %d\n"
478 "\n"
479 "# Section containing HIP related information\n"
480 "#\n"
481 "# issuerhit = what hit is to be used when signing\n"
482 "# days = how long is this key valid\n"
483 "\n"
484 "[ hip_x509v3 ]\n"
485 "issuerhit = %s\n"
486 "days = %d\n"
487 "\n"
488 "#Section containing the name section for the x509v3 issuer name"
489 "\n"
490 "[ hip_x509v3_name ]\n"
491 "issuerhit = %s\n"
492 "\n"
493 "# Uncomment this section to add x509 extensions\n"
494 "# to the certificate\n"
495 "#\n"
496 "# DO NOT use subjectAltName, issuerAltName or\n"
497 "# basicConstraints implementation uses them already\n"
498 "# All other extensions are allowed\n"
499 "\n"
500 "# [ hip_x509v3_extensions ]\n",
501 hit, HIP_CERT_INIT_DAYS,
502 hit, HIP_CERT_INIT_DAYS,
503 hit /* TODO SAMU: removed because not used:*/ /*, hostname*/);
504 } else {
505 HIP_DEBUG("Configuration file existed exiting init_certs\n");
506 }
507 fclose(conf_file);
508
509out_err:
510 return err;
511}
512
513static void init_packet_types(void)438static void init_packet_types(void)
514{439{
515 lmod_register_packet_type(HIP_I1, "HIP_I1");440 lmod_register_packet_type(HIP_I1, "HIP_I1");
@@ -894,7 +819,7 @@
894 */819 */
895int hipd_init(const uint64_t flags)820int hipd_init(const uint64_t flags)
896{821{
897 int err = 0, certerr = 0, i, j;822 int err = 0, i, j;
898 int killold = (flags & HIPD_START_KILL_OLD) > 0;823 int killold = (flags & HIPD_START_KILL_OLD) > 0;
899 unsigned int mtu_val = HIP_HIT_DEV_MTU;824 unsigned int mtu_val = HIP_HIT_DEV_MTU;
900 char str[64];825 char str[64];
@@ -1035,12 +960,6 @@
1035 return -1;960 return -1;
1036 }961 }
1037962
1038 certerr = 0;
1039 certerr = init_certs();
1040 if (certerr < 0) {
1041 HIP_DEBUG("Initializing cert configuration file returned error\n");
1042 }
1043
1044 /* Service initialization. */963 /* Service initialization. */
1045 hip_init_services();964 hip_init_services();
1046965
1047966
=== modified file 'hipd/input.c'
--- hipd/input.c 2012-02-17 10:45:47 +0000
+++ hipd/input.c 2012-02-20 21:55:24 +0000
@@ -73,7 +73,6 @@
73#include "netdev.h"73#include "netdev.h"
74#include "opp_mode.h"74#include "opp_mode.h"
75#include "output.h"75#include "output.h"
76#include "pisa.h"
77#include "pkt_handling.h"76#include "pkt_handling.h"
78#include "registration.h"77#include "registration.h"
79#include "input.h"78#include "input.h"
8079
=== modified file 'hipd/output.c'
--- hipd/output.c 2012-02-15 17:37:10 +0000
+++ hipd/output.c 2012-02-20 21:55:24 +0000
@@ -65,7 +65,6 @@
65#include "hiprelay.h"65#include "hiprelay.h"
66#include "nat.h"66#include "nat.h"
67#include "netdev.h"67#include "netdev.h"
68#include "pisa.h"
69#include "registration.h"68#include "registration.h"
70#include "output.h"69#include "output.h"
7170
7271
=== removed file 'hipd/pisa.c'
--- hipd/pisa.c 2011-10-25 21:14:16 +0000
+++ hipd/pisa.c 1970-01-01 00:00:00 +0000
@@ -1,83 +0,0 @@
1/*
2 * Copyright (c) 2010 Aalto University and RWTH Aachen University.
3 *
4 * Permission is hereby granted, free of charge, to any person
5 * obtaining a copy of this software and associated documentation
6 * files (the "Software"), to deal in the Software without
7 * restriction, including without limitation the rights to use,
8 * copy, modify, merge, publish, distribute, sublicense, and/or sell
9 * copies of the Software, and to permit persons to whom the
10 * Software is furnished to do so, subject to the following
11 * conditions:
12 *
13 * The above copyright notice and this permission notice shall be
14 * included in all copies or substantial portions of the Software.
15 *
16 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
17 * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
18 * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
19 * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
20 * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
21 * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
22 * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
23 * OTHER DEALINGS IN THE SOFTWARE.
24 */
25
26/**
27 * @file
28 * This file contains functions that are specific to PISA. They deal with the
29 * certificate loading.
30 *
31 * @brief Functions for certificate loading
32 */
33
34#include <stdio.h>
35#include <stdlib.h>
36#include <string.h>
37
38#include "config.h"
39#include "lib/core/debug.h"
40#include "hipd.h"
41#include "pisa.h"
42
43#define CERT_MAX_SIZE 1024
44
45static char *midauth_cert = NULL;
46
47/**
48 * Load a certificate from the file HIPL_SYSCONFDIR/cert and store it in memory
49 *
50 * @return 0 on success
51 */
52static int pisa_load_certificate(void)
53{
54 FILE *f = NULL;
55
56 free(midauth_cert);
57 midauth_cert = calloc(1, CERT_MAX_SIZE);
58
59 if (!(f = fopen(HIPL_SYSCONFDIR "/cert", "r"))) {
60 HIP_ERROR("Could not open certificate file.\n");
61 return -1;
62 }
63
64 if (fread(midauth_cert, CERT_MAX_SIZE - 1, 1, f) == 0) {
65 perror("fread returned 0");
66 }
67 fclose(f);
68 return 0;
69}
70
71/**
72 * Load a certificate from disk and return a pointer to the global
73 * variable containing it.
74 *
75 * @see pisa_load_certificate*
76 *
77 * @return pointer to midauth_cert
78 */
79char *hip_pisa_get_certificate(void)
80{
81 pisa_load_certificate();
82 return midauth_cert;
83}
840
=== removed file 'hipd/pisa.h'
--- hipd/pisa.h 2011-11-25 17:56:24 +0000
+++ hipd/pisa.h 1970-01-01 00:00:00 +0000
@@ -1,44 +0,0 @@
1/*
2 * Copyright (c) 2010 Aalto University and RWTH Aachen University.
3 *
4 * Permission is hereby granted, free of charge, to any person
5 * obtaining a copy of this software and associated documentation
6 * files (the "Software"), to deal in the Software without
7 * restriction, including without limitation the rights to use,
8 * copy, modify, merge, publish, distribute, sublicense, and/or sell
9 * copies of the Software, and to permit persons to whom the
10 * Software is furnished to do so, subject to the following
11 * conditions:
12 *
13 * The above copyright notice and this permission notice shall be
14 * included in all copies or substantial portions of the Software.
15 *
16 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
17 * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
18 * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
19 * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
20 * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
21 * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
22 * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
23 * OTHER DEALINGS IN THE SOFTWARE.
24 */
25
26/**
27 * @file
28 * This file contains function declarations specific to PISA. They deal with the
29 * certificate loading.
30 *
31 * @brief Functions declarations for certificate loading
32 */
33
34#ifndef HIPL_HIPD_PISA_H
35#define HIPL_HIPD_PISA_H
36
37/**
38 * Get the certificate text that will be appended to R2 and U2 packets
39 *
40 * @return pointer to the certificate text
41 */
42char *hip_pisa_get_certificate(void);
43
44#endif /* HIPL_HIPD_PISA_H */
450
=== modified file 'hipd/user.c'
--- hipd/user.c 2012-02-15 17:37:10 +0000
+++ hipd/user.c 2012-02-20 21:55:24 +0000
@@ -65,7 +65,6 @@
65#include "lib/tool/nlink.h"65#include "lib/tool/nlink.h"
66#include "config.h"66#include "config.h"
67#include "accessor.h"67#include "accessor.h"
68#include "cert.h"
69#include "close.h"68#include "close.h"
70#include "cookie.h"69#include "cookie.h"
71#include "esp_prot_anchordb.h"70#include "esp_prot_anchordb.h"
@@ -240,7 +239,7 @@
240{239{
241 const hip_hit_t *src_hit = NULL, *dst_hit = NULL;240 const hip_hit_t *src_hit = NULL, *dst_hit = NULL;
242 struct hip_hadb_state *entry = NULL;241 struct hip_hadb_state *entry = NULL;
243 int err = 0, msg_type = 0, reti = 0;242 int err = 0, msg_type = 0;
244 int access_ok = 0, is_root = 0, name_len;243 int access_ok = 0, is_root = 0, name_len;
245 const struct hip_tlv_common *param = NULL;244 const struct hip_tlv_common *param = NULL;
246 const struct hip_transformation_order *transorder;245 const struct hip_transformation_order *transorder;
@@ -359,40 +358,6 @@
359 dst_hit = hip_get_param_contents(msg, HIP_PARAM_HIT);358 dst_hit = hip_get_param_contents(msg, HIP_PARAM_HIT);
360 hip_dec_cookie_difficulty();359 hip_dec_cookie_difficulty();
361 break;360 break;
362 case HIP_MSG_CERT_SPKI_VERIFY:
363 {
364 HIP_DEBUG("Got an request to verify SPKI cert\n");
365 reti = hip_cert_spki_verify(msg);
366 HIP_IFEL(reti, -1, "Verifying SPKI cert returned an error\n");
367 HIP_DEBUG("SPKI cert verified sending it back to requester\n");
368 }
369 break;
370 case HIP_MSG_CERT_SPKI_SIGN:
371 {
372 HIP_DEBUG("Got an request to sign SPKI cert sequence\n");
373 reti = hip_cert_spki_sign(msg);
374 HIP_IFEL(reti, -1, "Signing SPKI cert returned an error\n");
375 HIP_DEBUG("SPKI cert signed sending it back to requester\n");
376 }
377 break;
378 case HIP_MSG_CERT_X509V3_SIGN:
379 {
380 HIP_DEBUG("Got an request to sign X509v3 cert\n");
381 reti = hip_cert_x509v3_handle_request_to_sign(msg);
382 HIP_IFEL(reti, -1, "Signing of x509v3 cert returned an error\n");
383 HIP_DEBUG("X509v3 cert signed sending it back to requester\n");
384 }
385 break;
386 case HIP_MSG_CERT_X509V3_VERIFY:
387 {
388 HIP_DEBUG("Got an request to verify X509v3 cert\n");
389 reti = hip_cert_x509v3_handle_request_to_verify(msg);
390 HIP_IFEL(reti, -1, "Verification of x509v3 cert "
391 "returned an error\n");
392 HIP_DEBUG("X509v3 verification ended "
393 "sending it back to requester\n");
394 }
395 break;
396 case HIP_MSG_TRANSFORM_ORDER:361 case HIP_MSG_TRANSFORM_ORDER:
397 {362 {
398 err = 0;363 err = 0;
399364
=== modified file 'hipfw/conntrack.c'
--- hipfw/conntrack.c 2012-02-17 18:01:18 +0000
+++ hipfw/conntrack.c 2012-02-20 21:55:24 +0000
@@ -72,8 +72,8 @@
72#include "hipfw.h"72#include "hipfw.h"
73#include "helpers.h"73#include "helpers.h"
74#include "hslist.h"74#include "hslist.h"
75#include "pisa.h"
76#include "reinject.h"75#include "reinject.h"
76#include "midauth.h"
7777
7878
79static struct dlist *hip_list = NULL;79static struct dlist *hip_list = NULL;
@@ -1386,7 +1386,7 @@
1386 return 0;1386 return 0;
1387 }1387 }
13881388
1389 esp_tuple->spi = ntohl(esp_info->new_spi);1389 esp_tuple->spi = ntohl(esp_info->new_spi);
1390 esp_tuple->spi_update_id = seq->update_id;1390 esp_tuple->spi_update_id = seq->update_id;
13911391
1392 HIP_IFEL(!update_esp_dest_addr(locator, seq, esp_tuple),1392 HIP_IFEL(!update_esp_dest_addr(locator, seq, esp_tuple),
@@ -1400,7 +1400,7 @@
1400 return 0;1400 return 0;
1401 }1401 }
14021402
1403 esp_tuple->spi = ntohl(esp_info->new_spi);1403 esp_tuple->spi = ntohl(esp_info->new_spi);
1404 esp_tuple->spi_update_id = seq->update_id;1404 esp_tuple->spi_update_id = seq->update_id;
1405 } else if (locator && seq) {1405 } else if (locator && seq) {
1406 HIP_DEBUG("locator and seq\n");1406 HIP_DEBUG("locator and seq\n");
14071407
=== modified file 'hipfw/hipfw.c'
--- hipfw/hipfw.c 2011-11-25 16:40:40 +0000
+++ hipfw/hipfw.c 2012-02-20 21:55:24 +0000
@@ -87,7 +87,6 @@
87#include "helpers.h"87#include "helpers.h"
88#include "lsi.h"88#include "lsi.h"
89#include "midauth.h"89#include "midauth.h"
90#include "pisa.h"
91#include "port_bindings.h"90#include "port_bindings.h"
92#include "reinject.h"91#include "reinject.h"
93#include "rewrite.h"92#include "rewrite.h"
@@ -1885,12 +1884,6 @@
1885 continue;1884 continue;
1886 }1885 }
18871886
1888#ifdef CONFIG_HIP_PISA
1889 if (use_midauth) {
1890 pisa_check_for_random_update();
1891 }
1892#endif
1893
1894 if (FD_ISSET(h4->fd, &read_fdset)) {1887 if (FD_ISSET(h4->fd, &read_fdset)) {
1895 HIP_DEBUG("received IPv4 packet from iptables queue\n");1888 HIP_DEBUG("received IPv4 packet from iptables queue\n");
1896 err = fw_handle_packet(buf, h4, 4, &ctx);1889 err = fw_handle_packet(buf, h4, 4, &ctx);
18971890
=== removed file 'hipfw/pisa.c'
--- hipfw/pisa.c 2011-11-25 13:52:20 +0000
+++ hipfw/pisa.c 1970-01-01 00:00:00 +0000
@@ -1,575 +0,0 @@
1/*
2 * Copyright (c) 2010 Aalto University and RWTH Aachen University.
3 *
4 * Permission is hereby granted, free of charge, to any person
5 * obtaining a copy of this software and associated documentation
6 * files (the "Software"), to deal in the Software without
7 * restriction, including without limitation the rights to use,
8 * copy, modify, merge, publish, distribute, sublicense, and/or sell
9 * copies of the Software, and to permit persons to whom the
10 * Software is furnished to do so, subject to the following
11 * conditions:
12 *
13 * The above copyright notice and this permission notice shall be
14 * included in all copies or substantial portions of the Software.
15 *
16 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
17 * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
18 * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
19 * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
20 * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
21 * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
22 * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
23 * OTHER DEALINGS IN THE SOFTWARE.
24 */
25
26/**
27 * @file
28 * This file contains PISA specific functions for the firewall. The basic idea
29 * is to modify the HIP messages and manage state for allowed connections to
30 * allow or reject associated ESP traffic.
31 *
32 * @brief PISA functions for the firewall
33 */
34
35#define _BSD_SOURCE
36
37#include <stdint.h>
38#include <stdio.h>
39#include <stdlib.h>
40#include <string.h>
41#include <time.h>
42#include <arpa/inet.h>
43#include <netinet/in.h>
44#include <linux/netfilter.h>
45#include <openssl/hmac.h>
46
47#include "config.h"
48#include "lib/core/builder.h"
49#include "lib/core/certtools.h"
50#include "lib/core/crypto.h"
51#include "lib/core/debug.h"
52#include "lib/core/ife.h"
53#include "lib/core/performance.h"
54#include "lib/core/prefix.h"
55#include "modules/midauth/hipd/midauth.h"
56#include "conntrack.h"
57#include "hipfw_defines.h"
58#include "midauth.h"
59#include "pisa_cert.h"
60#include "pisa.h"
61
62
63#define PISA_RANDOM_LEN 16
64#define PISA_PUZZLE_SEED 0xDEADC0DE
65#define PISA_PUZZLE_OPAQUE_LEN (4 + HIP_AH_SHA_LEN)
66
67/* pisa_check_for_random_update is called at least every PISA_RANDOM_TTL
68 * seconds. Worst case timer resolution depends on the timeout in the select
69 * call */
70#define PISA_RANDOM_TTL 2.0
71
72static char pisa_random_data[2][PISA_RANDOM_LEN];
73static struct in6_addr community_operator_hit;
74
75/* @todo make this configurable, issuer HIT */
76#define CO_HIT "2001:001a:b1b0:0aad:0f92:15ca:280c:9430"
77#define CO_HIT_FILE HIPL_SYSCONFDIR "/co_hit"
78
79/**
80 * Generate a new random number and shift the old one down.
81 */
82static void pisa_generate_random(void)
83{
84 void *p0, *p1;
85
86 p0 = &pisa_random_data[0][0];
87 p1 = &pisa_random_data[1][0];
88
89 memcpy(p0, p1, PISA_RANDOM_LEN);
90 get_random_bytes(p1, PISA_RANDOM_LEN);
91}
92
93/**
94 * Reads out the HIT of the Community-Operator
95 * from file CO_HIT_FILE
96 * @param hit A pointer to the char where the HIT should be stored
97 * @return 1-> success
98 * @return 0-> error
99 */
100static int pisa_read_communit_operator_hit(char *hit)
101{
102 FILE *f;
103 char *eofline;
104
105 f = fopen(CO_HIT_FILE, "r");
106
107 if (f == NULL) {
108 return 0;
109 }
110
111 if (fgets(hit, INET6_ADDRSTRLEN, f) != NULL) {
112 eofline = strchr(hit, '\n');
113 if (eofline) {
114 *eofline = '\0';
115 }
116 } else {
117 HIP_ERROR("Fgets failed");
118 }
119 fclose(f);
120
121 return 1;
122}
123
124void pisa_check_for_random_update(void)
125{
126 static time_t lastupdate = 0;
127 time_t now;
128
129 time(&now);
130 if (difftime(now, lastupdate) > PISA_RANDOM_TTL) {
131 pisa_generate_random();
132 lastupdate = now;
133 }
134}
135
136/**
137 * Appends HMAC/SHA1 to a block of data.
138 *
139 * @param hit1 first HIT
140 * @param hit2 second HIT
141 * @param rnd which random number to use, either 0 or 1
142 * @param data pointer to buffer for data and the HMAC
143 * @param data_len length of data
144 * @return 0 on success
145 */
146static int pisa_append_hmac(struct in6_addr *hit1, struct in6_addr *hit2,
147 int rnd, void *data, int data_len)
148{
149 uint8_t key[32 + PISA_RANDOM_LEN];
150 int err = 0;
151 unsigned int len = HIP_AH_SHA_LEN;
152
153 /* sanity checks for arguments */
154 HIP_IFEL(data == NULL, -1, "No data given.\n");
155 HIP_IFEL(hit1 == NULL, -1, "No first HIT given.\n");
156 HIP_IFEL(hit2 == NULL, -1, "No second HIT given.\n");
157 HIP_IFEL(data_len < 1, -1, "Data has invalid length.\n");
158 HIP_IFEL(rnd != 0 && rnd != 1, -1, "Random ID is neither 0 nor 1.\n");
159
160 /* The key for HMAC/SHA1 consists of:
161 * 16 bytes HIT1
162 * 16 bytes HIT2
163 * PISA_RANDOM_LEN bytes pisa_random_data
164 */
165
166 ipv6_addr_copy((struct in6_addr *) (key + 0), hit1);
167 ipv6_addr_copy((struct in6_addr *) (key + 16), hit2);
168 memcpy(key + 32, &pisa_random_data[rnd][0], PISA_RANDOM_LEN);
169
170 HMAC(EVP_sha1(), key, 32 + PISA_RANDOM_LEN, data, data_len,
171 (uint8_t *) data + data_len, &len);
172
173out_err:
174 return err;
175}
176
177/**
178 * Insert a PISA puzzle into a packet.
179 *
180 * @param ctx context of the packet where the puzzle will be inserted
181 * @return success (0) or failure
182 */
183static int pisa_insert_puzzle(struct hip_fw_context *ctx)
184{
185 uint8_t opaque[PISA_PUZZLE_OPAQUE_LEN];
186
187 struct hip_common *hip = ctx->transport_hdr.hip;
188 int seed = PISA_PUZZLE_SEED;
189
190 memcpy(&opaque, &seed, 4);
191
192 /* here we switch order of initiator and receiver to obtain a
193 * different SHA1 hash */
194 pisa_append_hmac(&hip->hitr, &hip->hits, 1, &opaque, 4);
195
196 return midauth_add_challenge_request(ctx, 3, 4, opaque, PISA_PUZZLE_OPAQUE_LEN);
197}
198
199/**
200 * Check the validity of a PISA challenge_response.
201 *
202 * @param ctx context of the packet with the puzzle to check
203 * @return pointer to the puzzle we accepted or NULL at failure
204 */
205static struct hip_challenge_response *pisa_check_challenge_response(struct hip_fw_context *ctx)
206{
207 struct hip_challenge_response *response;
208 struct hip_common *hip = ctx->transport_hdr.hip;
209 uint8_t hash[2][PISA_PUZZLE_OPAQUE_LEN];
210 int seed = PISA_PUZZLE_SEED;
211
212 memcpy(&hash[0][0], &seed, 4);
213 memcpy(&hash[1][0], &seed, 4);
214
215 pisa_append_hmac(&hip->hits, &hip->hitr, 0, &hash[0], 4);
216 pisa_append_hmac(&hip->hits, &hip->hitr, 1, &hash[1], 4);
217
218 response = hip_get_param_readwrite(hip, HIP_PARAM_CHALLENGE_RESPONSE);
219
220 while (response) {
221 /* loop over all HIP_PARAM_CHALLENGE_RESPONSE */
222 if (hip_get_param_type(response) != HIP_PARAM_CHALLENGE_RESPONSE) {
223 break;
224 }
225 if ((!memcmp(response->opaque, &hash[1][0], PISA_PUZZLE_OPAQUE_LEN)) ||
226 (!memcmp(response->opaque, &hash[0][0], PISA_PUZZLE_OPAQUE_LEN))) {
227 if (!midauth_verify_challenge_response(response,
228 hip->hits,
229 hip->hitr)) {
230 return response;
231 }
232 }
233
234 response = (struct hip_challenge_response *)
235 hip_get_next_param_readwrite(hip,
236 (struct hip_tlv_common *) response);
237 }
238
239 return NULL;
240}
241
242/**
243 * Check the certificate of the packet.
244 *
245 * @param ctx context of the packet with the certificate to check
246 * @return success (0) or failure
247 */
248static int pisa_check_certificate(struct hip_fw_context *ctx)
249{
250 struct hip_common *hip = ctx->transport_hdr.hip;
251 const struct hip_cert *cert;
252 struct hip_cert_spki_info ci;
253 struct pisa_cert pc;
254 char *buf = NULL;
255 int err = 0, len;
256 time_t now = time(NULL);
257
258 cert = hip_get_param(hip, HIP_PARAM_CERT);
259 HIP_IFEL(cert == NULL, -1, "No certificate found.\n");
260
261 len = ntohs(cert->length);
262 buf = calloc(1, len);
263 memcpy(buf, cert + 1, len);
264
265 HIP_IFEL(hip_cert_spki_char2certinfo(buf, &ci), -1,
266 "Certificate could not be parsed.\n");
267 HIP_IFEL(hip_cert_spki_lib_verify(&ci), -1,
268 "Certificate could not be verified.\n");
269
270 pisa_split_cert(ci.cert, &pc);
271
272 /* Three conditions must be fulfilled for a certificate to be valid:
273 *
274 * - The current time on the middlebox must be in the before/after
275 * interval
276 * - The certificate must be issued by the community operator (i.e.
277 * the CO HIT must be used by the issuer)
278 * - The host sending the certificate must be the one mentioned in
279 * the certificate
280 */
281 HIP_IFEL(now < pc.not_before, -1,
282 "Certificate is not valid yet.\n");
283 HIP_IFEL(now > pc.not_after, -1,
284 "Certificate has expired.\n");
285
286
287 HIP_IFEL(ipv6_addr_cmp(&pc.hit_issuer, &community_operator_hit) != 0,
288 -1, "Certificate not issued by the community operator.\n");
289 HIP_IFEL(ipv6_addr_cmp(&pc.hit_subject, &hip->hits) != 0, -1,
290 "Certificate does not belong to subject.\n");
291
292 HIP_INFO("Certificate successfully verified.\n");
293
294out_err:
295 free(buf);
296 return err;
297}
298
299/**
300 * Accept a connection via PISA. Update firewall to allow data packets to
301 * pass through.
302 *
303 * @param ctx context of the packet that belongs to that connection
304 */
305static void pisa_accept_connection(const struct hip_fw_context *ctx)
306{
307 struct hip_common *hip = ctx->transport_hdr.hip;
308 struct tuple *t = get_tuple_by_hits(&hip->hits, &hip->hitr);
309
310 if (t) {
311 t->connection->pisa_state = PISA_STATE_ALLOW;
312 HIP_INFO("PISA accepted the connection.\n");
313 hip_fw_manage_all_esp_tuples(t, true);
314 } else {
315 HIP_ERROR("Connection not found.\n");
316 }
317}
318
319/**
320 * Remove a connection from the list of accepted connections based on the hits
321 * of a packet.
322 *
323 * @param ctx context of the packet that contains HITs of the connection
324 */
325static void pisa_remove_connection(const struct hip_fw_context *ctx)
326{
327 struct hip_common *hip = ctx->transport_hdr.hip;
328 struct tuple *t = get_tuple_by_hits(&hip->hits, &hip->hitr);
329
330 if (t) {
331 t->connection->pisa_state = PISA_STATE_DISALLOW;
332 HIP_INFO("PISA removed the connection.\n");
333 hip_fw_manage_all_esp_tuples(t, false);
334 } else {
335 HIP_ERROR("Connection not found.\n");
336 }
337}
338
339/**
340 * Reject a connection via PISA. Update firewall to allow no data packets
341 * to pass through.
342 *
343 * @param ctx context of the packet that belongs to that connection
344 */
345static void pisa_reject_connection(const struct hip_fw_context *ctx)
346{
347 HIP_INFO("PISA rejected the connection.\n");
348 pisa_remove_connection(ctx);
349}
350
351/**
352 * Dummy function, necessary only for performance measurements.
353 *
354 * @param ctx context of the packet containing the I1
355 * @return NF_ACCEPT verdict
356 */
357static int pisa_handler_i1(UNUSED struct hip_fw_context *ctx)
358{
359#ifdef CONFIG_HIP_PERFORMANCE
360 HIP_DEBUG("Start PERF_BASE, PERF_I1\n");
361 hip_perf_start_benchmark(perf_set, PERF_BASE);
362 hip_perf_start_benchmark(perf_set, PERF_I1);
363#endif
364
365#ifdef CONFIG_HIP_PERFORMANCE
366 HIP_DEBUG("Stop and write PERF_I1\n");
367 hip_perf_stop_benchmark(perf_set, PERF_I1);
368 hip_perf_write_benchmark(perf_set, PERF_I1);
369#endif
370
371 return NF_ACCEPT;
372}
373
374/**
375 * Dummy function, necessary only for performance measurements.
376 *
377 * @param ctx context of the packet containing the R1
378 * @return NF_ACCEPT verdict
379 */
380static int pisa_handler_r1(UNUSED struct hip_fw_context *ctx)
381{
382#ifdef CONFIG_HIP_PERFORMANCE
383 HIP_DEBUG("Start PERF_R1\n");
384 hip_perf_start_benchmark(perf_set, PERF_R1);
385#endif
386
387#ifdef CONFIG_HIP_PERFORMANCE
388 HIP_DEBUG("Stop and write PERF_R1\n");
389 hip_perf_stop_benchmark(perf_set, PERF_R1);
390 hip_perf_write_benchmark(perf_set, PERF_R1);
391#endif
392
393 return NF_ACCEPT;
394}
395
396/**
397 * Insert a PISA puzzle into the I2 packet.
398 *
399 * @param ctx context of the packet to modify
400 * @return NF_ACCEPT verdict
401 */
402static int pisa_handler_i2(struct hip_fw_context *ctx)
403{
404#ifdef CONFIG_HIP_PERFORMANCE
405 HIP_DEBUG("Start PERF_I2\n");
406 hip_perf_start_benchmark(perf_set, PERF_I2);
407#endif
408 pisa_insert_puzzle(ctx);
409
410#ifdef CONFIG_HIP_PERFORMANCE
411 HIP_DEBUG("Stop and write PERF_I2\n");
412 hip_perf_stop_benchmark(perf_set, PERF_I2);
413 hip_perf_write_benchmark(perf_set, PERF_I2);
414#endif
415
416 return NF_ACCEPT;
417}
418
419/**
420 * Check for a PISA puzzle, a valid signature and a valid
421 * certificate in the R2 packet.
422 *
423 * @param ctx context of the packet to check
424 * @return verdict, either NF_ACCEPT or NF_DROP
425 */
426static int pisa_handler_r2(struct hip_fw_context *ctx)
427{
428 int verdict = NF_DROP, sig = 0, cert = 0;
429 struct hip_challenge_response *solution = NULL;
430
431#ifdef CONFIG_HIP_PERFORMANCE
432 HIP_DEBUG("Start PERF_R2\n");
433 hip_perf_start_benchmark(perf_set, PERF_R2);
434#endif
435
436 solution = pisa_check_challenge_response(ctx);
437 cert = pisa_check_certificate(ctx);
438
439 if (solution == NULL || sig != 0 || cert != 0) {
440 /* disallow further communication if either nonce, solution,
441 * signature or certificate were not correct */
442 pisa_reject_connection(ctx);
443 verdict = NF_DROP;
444 } else {
445 /* allow futher communication otherwise */
446 pisa_accept_connection(ctx);
447 verdict = NF_ACCEPT;
448 }
449
450#ifdef CONFIG_HIP_PERFORMANCE
451 HIP_DEBUG("Stop and write PERF_R2, PERF_BASE\n");
452 hip_perf_stop_benchmark(perf_set, PERF_R2);
453 hip_perf_stop_benchmark(perf_set, PERF_BASE);
454 hip_perf_write_benchmark(perf_set, PERF_R2);
455 hip_perf_write_benchmark(perf_set, PERF_BASE);
456#endif
457
458 return verdict;
459}
460
461/**
462 * Insert a PISA nonce and a PISA puzzle into the U1 packet.
463 *
464 * @param ctx context of the packet to modify
465 * @return NF_ACCEPT verdict
466 */
467static int pisa_handler_u1(struct hip_fw_context *ctx)
468{
469 pisa_insert_puzzle(ctx);
470
471 return NF_ACCEPT;
472}
473
474/**
475 * Check for a PISA nonce, a PISA puzzle, a valid signature and a valid
476 * certificate in the U2 packet.
477 *
478 * @param ctx context of the packet to check
479 * @return verdict, either NF_ACCEPT or NF_DROP
480 */
481static int pisa_handler_u2(struct hip_fw_context *ctx)
482{
483 int verdict = NF_DROP;
484 int sig = 0;
485 int cert = 0;
486 struct hip_challenge_response *solution = NULL;
487
488 solution = pisa_check_challenge_response(ctx);
489 cert = pisa_check_certificate(ctx);
490
491 if (solution == NULL || sig != 0 || cert != 0) {
492 HIP_DEBUG("U2 packet did not match criteria: "
493 "solution %p, signature %i, cert %i\n",
494 solution, sig, cert);
495 verdict = NF_DROP;
496 } else {
497 /* packet was ok, insert another puzzle */
498 pisa_insert_puzzle(ctx);
499 verdict = NF_ACCEPT;
500 }
501
502 return verdict;
503}
504
505/**
506 * Check for a PISA nonce and a valid signature in the U3 packet.
507 *
508 * @param ctx context of the packet to check
509 * @return verdict, either NF_ACCEPT or NF_DROP
510 */
511static int pisa_handler_u3(struct hip_fw_context *ctx)
512{
513 int verdict = NF_DROP;
514 int sig = 0;
515 struct hip_challenge_response *solution = NULL;
516
517 solution = pisa_check_challenge_response(ctx);
518
519 if (solution == NULL || sig != 0) {
520 HIP_DEBUG("U2 packet did not match criteria: "
521 "solution %p\n",
522 solution);
523 pisa_reject_connection(ctx);
524 verdict = NF_DROP;
525 } else {
526 pisa_accept_connection(ctx);
527 verdict = NF_ACCEPT;
528 }
529 return verdict;
530}
531
532/**
533 * Handle CLOSE_ACK packet. Remove the connection from the list of accepted
534 * connections
535 *
536 * @param ctx context of the packet
537 * @return verdict, either NF_ACCEPT or NF_DROP
538 */
539static int pisa_handler_close_ack(struct hip_fw_context *ctx)
540{
541 pisa_remove_connection(ctx);
542 return NF_ACCEPT;
543}
544
545/**
546 * Initialize basic PISA functionality
547 *
548 * @param h function pointers for packet handlers
549 */
550void pisa_init(struct midauth_handlers *h)
551{
552 char hit[INET6_ADDRSTRLEN];
553 h->i1 = pisa_handler_i1;
554 h->r1 = pisa_handler_r1;
555 h->i2 = pisa_handler_i2;
556 h->r2 = pisa_handler_r2;
557 h->u1 = pisa_handler_u1;
558 h->u2 = pisa_handler_u2;
559 h->u3 = pisa_handler_u3;
560 h->close = midauth_handler_accept;
561 h->close_ack = pisa_handler_close_ack;
562
563 pisa_generate_random();
564 pisa_generate_random();
565
566 if (!pisa_read_communit_operator_hit(hit)) {
567 hit[0] = '\0';
568 HIP_ERROR("Could not load Communit-Operator HIT from file %s\n",
569 CO_HIT_FILE);
570 }
571
572 if (inet_pton(AF_INET6, hit, &community_operator_hit) <= 0) {
573 HIP_ERROR("Coult not parse Community-Operator HIT\n");
574 }
575}
5760
=== removed file 'hipfw/pisa.h'
--- hipfw/pisa.h 2011-11-25 13:52:20 +0000
+++ hipfw/pisa.h 1970-01-01 00:00:00 +0000
@@ -1,48 +0,0 @@
1/*
2 * Copyright (c) 2010 Aalto University and RWTH Aachen University.
3 *
4 * Permission is hereby granted, free of charge, to any person
5 * obtaining a copy of this software and associated documentation
6 * files (the "Software"), to deal in the Software without
7 * restriction, including without limitation the rights to use,
8 * copy, modify, merge, publish, distribute, sublicense, and/or sell
9 * copies of the Software, and to permit persons to whom the
10 * Software is furnished to do so, subject to the following
11 * conditions:
12 *
13 * The above copyright notice and this permission notice shall be
14 * included in all copies or substantial portions of the Software.
15 *
16 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
17 * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
18 * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
19 * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
20 * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
21 * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
22 * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
23 * OTHER DEALINGS IN THE SOFTWARE.
24 */
25
26#ifndef HIPL_HIPFW_PISA_H
27#define HIPL_HIPFW_PISA_H
28
29#include "midauth.h"
30
31#define PISA_STATE_DISALLOW 0
32#define PISA_STATE_ALLOW 1
33
34#ifdef CONFIG_HIP_PISA
35/**
36 * Register PISA handlers with midauth and initialize data structures.
37 *
38 * @param h pointer to the handlers
39 */
40void pisa_init(struct midauth_handlers *h);
41#endif
42
43/**
44 * Check if a new random number is necessary.
45 */
46void pisa_check_for_random_update(void);
47
48#endif /* HIPL_HIPFW_PISA_H */
490
=== removed file 'hipfw/pisa_cert.c'
--- hipfw/pisa_cert.c 2011-08-15 14:11:56 +0000
+++ hipfw/pisa_cert.c 1970-01-01 00:00:00 +0000
@@ -1,205 +0,0 @@
1/*
2 * Copyright (c) 2010 Aalto University and RWTH Aachen University.
3 *
4 * Permission is hereby granted, free of charge, to any person
5 * obtaining a copy of this software and associated documentation
6 * files (the "Software"), to deal in the Software without
7 * restriction, including without limitation the rights to use,
8 * copy, modify, merge, publish, distribute, sublicense, and/or sell
9 * copies of the Software, and to permit persons to whom the
10 * Software is furnished to do so, subject to the following
11 * conditions:
12 *
13 * The above copyright notice and this permission notice shall be
14 * included in all copies or substantial portions of the Software.
15 *
16 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
17 * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
18 * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
19 * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
20 * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
21 * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
22 * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
23 * OTHER DEALINGS IN THE SOFTWARE.
24 */
25
26/**
27 * @file
28 * This file deals with the PISA specific handling of SPKI certificates. The
29 * certificate is parsed and split into small chunks.
30 *
31 * @brief PISA handling for SPKI certificates
32 */
33
34#define _BSD_SOURCE
35
36#include <string.h>
37#include <time.h>
38#include <arpa/inet.h>
39#include <netinet/in.h>
40#include <sys/types.h>
41
42#include "pisa_cert.h"
43
44
45/**
46 * Extract parts of a SPKI certificate.
47 *
48 * @param cert pointer to the certificate text or part of a certificate text
49 * @param name pointer to the pattern we are looking for
50 * @param r pointer to a buffer that the search result will be copied to
51 * @return 0 on success
52 */
53static char *pisa_cert_get_part(char *cert, const char *name, char *r)
54{
55 int level = 0, len = 0;
56 char *p = cert, *start = NULL;
57
58 if (!r) {
59 return NULL;
60 }
61
62 if (!cert) {
63 goto out_err;
64 }
65
66 if (!name) {
67 goto out_err;
68 }
69
70 len = strlen(name);
71 if (len == 0) {
72 goto out_err;
73 }
74
75 while (*p) {
76 if (*p == '(') {
77 level++;
78 if (level == 2 && !strncmp(p + 1, name, len)) {
79 if (*(p + len + 1) == ' ') {
80 start = p++;
81 break;
82 }
83 }
84 }
85 if (*p == ')') {
86 level--;
87 }
88 if (level == 0) {
89 break;
90 }
91 p++;
92 }
93
94 if (!start) {
95 goto out_err;
96 }
97
98 len = 0;
99
100 while (*p) {
101 if (*p == '(') {
102 level++;
103 }
104 if (*p == ')') {
105 level--;
106 if (level == 1) {
107 len = p - start + 1;
108 break;
109 }
110 }
111 if (level == 0) {
112 break;
113 }
114 p++;
115 }
116
117 strncpy(r, start, len);
118 r[len] = '\0';
119
120 return r;
121
122out_err:
123 r[0] = '\0';
124 return NULL;
125}
126
127/**
128 * Get the content from a SPKI certificate part.
129 *
130 * @param cert pointer to the certificate text or part of a certificate text
131 * @param name pointer to the pattern we are looking for
132 * @param r pointer to a buffer that the search result will be copied to
133 * @return 0 on success
134 */
135static void pisa_cert_get_content(char *cert, const char *name, char *r)
136{
137 char *start = cert;
138 int len = 0;
139
140 if (!r) {
141 return;
142 }
143
144 if (!cert || !name || !*name == '(') {
145 goto out_err;
146 }
147
148 if (strlen(name) + 3 > strlen(cert)) {
149 goto out_err;
150 }
151
152 if (strncmp(name, cert + 1, strlen(name))) {
153 goto out_err;
154 }
155 start = cert + strlen(name) + 2;
156
157 if (*start == '\0') {
158 goto out_err;
159 }
160
161 len = strlen(start) - 1;
162 if (*(start + len) != ')') {
163 goto out_err;
164 }
165 strncpy(r, start, len);
166
167out_err:
168 r[len] = '\0';
169}
170
171/**
172 * Splits a certificate into semantic chunks and converts these to
173 * sensible binary representations.
174 *
175 * @param cert the original certificate
176 * @param pc internal representation of the certificate
177 */
178void pisa_split_cert(char *cert, struct pisa_cert *pc)
179{
180 struct tm t;
181 char buffer1[224], buffer2[224];
182 struct in6_addr addr;
183
184 pisa_cert_get_part(cert, "not-before", buffer1);
185 pisa_cert_get_content(buffer1, "not-before", buffer2);
186 strptime(buffer2, "\"%Y-%m-%d_%H:%M:%S\"", &t);
187 pc->not_before = mktime(&t);
188
189 pisa_cert_get_part(cert, "not-after", buffer1);
190 pisa_cert_get_content(buffer1, "not-after", buffer2);
191 strptime(buffer2, "\"%Y-%m-%d_%H:%M:%S\"", &t);
192 pc->not_after = mktime(&t);
193
194 pisa_cert_get_part(cert, "issuer", buffer1);
195 pisa_cert_get_part(buffer1, "hash hit", buffer2);
196 pisa_cert_get_content(buffer2, "hash hit", buffer1);
197 inet_pton(AF_INET6, buffer1, &addr);
198 memcpy(&pc->hit_issuer, &addr, sizeof(struct in6_addr));
199
200 pisa_cert_get_part(cert, "subject", buffer1);
201 pisa_cert_get_part(buffer1, "hash hit", buffer2);
202 pisa_cert_get_content(buffer2, "hash hit", buffer1);
203 inet_pton(AF_INET6, buffer1, &addr);
204 memcpy(&pc->hit_subject, &addr, sizeof(struct in6_addr));
205}
2060
=== removed file 'hipfw/pisa_cert.h'
--- hipfw/pisa_cert.h 2011-11-25 13:52:20 +0000
+++ hipfw/pisa_cert.h 1970-01-01 00:00:00 +0000
@@ -1,47 +0,0 @@
1/*
2 * Copyright (c) 2010 Aalto University and RWTH Aachen University.
3 *
4 * Permission is hereby granted, free of charge, to any person
5 * obtaining a copy of this software and associated documentation
6 * files (the "Software"), to deal in the Software without
7 * restriction, including without limitation the rights to use,
8 * copy, modify, merge, publish, distribute, sublicense, and/or sell
9 * copies of the Software, and to permit persons to whom the
10 * Software is furnished to do so, subject to the following
11 * conditions:
12 *
13 * The above copyright notice and this permission notice shall be
14 * included in all copies or substantial portions of the Software.
15 *
16 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
17 * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
18 * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
19 * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
20 * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
21 * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
22 * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
23 * OTHER DEALINGS IN THE SOFTWARE.
24 */
25
26#ifndef HIPL_HIPFW_PISA_CERT_H
27#define HIPL_HIPFW_PISA_CERT_H
28
29#include <time.h>
30#include <netinet/in.h>
31
32struct pisa_cert {
33 struct in6_addr hit_issuer;
34 struct in6_addr hit_subject;
35 time_t not_before;
36 time_t not_after;
37};
38
39/**
40 * Split the hip_cert_spki_info.cert part into small chunks
41 *
42 * @param cert the hip_cert_spki_info.cert part of the certificate
43 * @param pc datastructure that will contain the chunks
44 */
45void pisa_split_cert(char *cert, struct pisa_cert *pc);
46
47#endif /* HIPL_HIPFW_PISA_CERT_H */
480
=== modified file 'lib/core/builder.c'
--- lib/core/builder.c 2012-01-10 17:53:47 +0000
+++ lib/core/builder.c 2012-02-20 21:55:24 +0000
@@ -3326,107 +3326,6 @@
3326}3326}
33273327
3328/**3328/**
3329 * Build and append a SPKI infor parameter into a HIP control message (on-the-wire)
3330 *
3331 * @param msg a pointer to the message where the parameter will be
3332 * appended
3333 * @param cert_info certificate information
3334 * @return zero on success, or negative on failure
3335 * @see <a href="http://tools.ietf.org/html/draft-ietf-hip-cert">draft-ietf-hip-cert</a>
3336 *
3337 */
3338int hip_build_param_cert_spki_info(struct hip_common *msg,
3339 struct hip_cert_spki_info *cert_info)
3340{
3341 struct hip_cert_spki_info local;
3342
3343 memcpy(&local, cert_info, sizeof(struct hip_cert_spki_info));
3344 hip_set_param_type((struct hip_tlv_common *) &local,
3345 HIP_PARAM_CERT_SPKI_INFO);
3346 hip_calc_param_len((struct hip_tlv_common *) &local,
3347 sizeof(struct hip_cert_spki_info)
3348 - sizeof(struct hip_tlv_common));
3349
3350 return hip_build_param(msg, &local);
3351}
3352
3353/**
3354 * Build and append a X509 certiticate request parameter into a HIP control
3355 * message (on-the-wire)
3356 *
3357 * @param msg a pointer to the message where the parameter will be
3358 * appended
3359 * @param addr the subject for the certificate
3360 * @return zero on success, or negative on failure
3361 * @see <a href="http://tools.ietf.org/html/draft-ietf-hip-cert">draft-ietf-hip-cert</a>
3362 *
3363 */
3364int hip_build_param_cert_x509_req(struct hip_common *msg, struct in6_addr *addr)
3365{
3366 struct hip_cert_x509_req subj;
3367
3368 hip_set_param_type((struct hip_tlv_common *) &subj, HIP_PARAM_CERT_X509_REQ);
3369 hip_calc_param_len((struct hip_tlv_common *) &subj,
3370 sizeof(struct hip_cert_x509_req)
3371 - sizeof(struct hip_tlv_common));
3372 ipv6_addr_copy(&subj.addr, addr);
3373
3374 return hip_build_param(msg, &subj);
3375}
3376
3377/**
3378 * build and append a X509 certificate verification parameter into a
3379 * HIP control message (on-the-wire)
3380 *
3381 * @param msg a pointer to the message where the parameter will be
3382 * appended
3383 * @param der der field
3384 * @param len length of the der field in bytes
3385 * @return zero on success, or negative on failure
3386 * @see <a href="http://tools.ietf.org/html/draft-ietf-hip-cert">draft-ietf-hip-cert</a>
3387 *
3388 */
3389int hip_build_param_cert_x509_ver(struct hip_common *msg, char *der, int len)
3390{
3391 struct hip_cert_x509_resp subj;
3392
3393 hip_set_param_type((struct hip_tlv_common *) &subj, HIP_PARAM_CERT_X509_REQ);
3394 hip_calc_param_len((struct hip_tlv_common *) &subj,
3395 sizeof(struct hip_cert_x509_resp)
3396 - sizeof(struct hip_tlv_common));
3397 memcpy(&subj.der, der, len);
3398 subj.der_len = len;
3399
3400 return hip_build_param(msg, &subj);
3401}
3402
3403/**
3404 * build and append a X509 certificate response into a HIP control message
3405 * (on-the-wire)
3406 *
3407 * @param msg a pointer to the message where the parameter will be
3408 * appended
3409 * @param der der field
3410 * @param len length of the der field in bytes
3411 * @return zero on success, or negative on failure
3412 * @see <a href="http://tools.ietf.org/html/draft-ietf-hip-cert">draft-ietf-hip-cert</a>
3413 *
3414 */
3415int hip_build_param_cert_x509_resp(struct hip_common *msg, char *der, int len)
3416{
3417 struct hip_cert_x509_resp local;
3418 hip_set_param_type((struct hip_tlv_common *) &local,
3419 HIP_PARAM_CERT_X509_RESP);
3420 hip_calc_param_len((struct hip_tlv_common *) &local,
3421 sizeof(struct hip_cert_x509_resp)
3422 - sizeof(struct hip_tlv_common));
3423 memcpy(&local.der, der, len);
3424 local.der_len = len;
3425
3426 return hip_build_param(msg, &local);
3427}
3428
3429/**
3430 * Build an append a zone parameter for hit-to-ip extension.3329 * Build an append a zone parameter for hit-to-ip extension.
3431 *3330 *
3432 * @param msg a pointer to the message where the parameter will be3331 * @param msg a pointer to the message where the parameter will be
34333332
=== modified file 'lib/core/builder.h'
--- lib/core/builder.h 2011-04-04 11:46:20 +0000
+++ lib/core/builder.h 2012-02-20 21:55:24 +0000
@@ -36,7 +36,6 @@
36#include <openssl/ec.h>36#include <openssl/ec.h>
37#endif /* HAVE_EC_CRYPTO */37#endif /* HAVE_EC_CRYPTO */
3838
39#include "certtools.h"
40#include "debug.h"39#include "debug.h"
41#include "icomm.h"40#include "icomm.h"
42#include "state.h"41#include "state.h"
@@ -156,11 +155,6 @@
156 const in_port_t port);155 const in_port_t port);
157int hip_build_param_via_rvs(struct hip_common *msg,156int hip_build_param_via_rvs(struct hip_common *msg,
158 const struct in6_addr rvs_addresses[]);157 const struct in6_addr rvs_addresses[]);
159int hip_build_param_cert_spki_info(struct hip_common *msg,
160 struct hip_cert_spki_info *cert_info);
161int hip_build_param_cert_x509_req(struct hip_common *, struct in6_addr *);
162int hip_build_param_cert_x509_resp(struct hip_common *, char *, int);
163int hip_build_param_cert_x509_ver(struct hip_common *, char *, int);
164158
165int hip_build_param_hit_to_ip_set(struct hip_common *, const char *);159int hip_build_param_hit_to_ip_set(struct hip_common *, const char *);
166int hip_build_user_hdr(struct hip_common *, hip_hdr, hip_hdr_err);160int hip_build_user_hdr(struct hip_common *, hip_hdr, hip_hdr_err);
167161
=== removed file 'lib/core/certtools.c'
--- lib/core/certtools.c 2012-01-14 15:29:47 +0000
+++ lib/core/certtools.c 1970-01-01 00:00:00 +0000
@@ -1,856 +0,0 @@
1/*
2 * Copyright (c) 2010 Aalto University and RWTH Aachen University.
3 *
4 * Permission is hereby granted, free of charge, to any person
5 * obtaining a copy of this software and associated documentation
6 * files (the "Software"), to deal in the Software without
7 * restriction, including without limitation the rights to use,
8 * copy, modify, merge, publish, distribute, sublicense, and/or sell
9 * copies of the Software, and to permit persons to whom the
10 * Software is furnished to do so, subject to the following
11 * conditions:
12 *
13 * The above copyright notice and this permission notice shall be
14 * included in all copies or substantial portions of the Software.
15 *
16 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
17 * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
18 * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
19 * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
20 * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
21 * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
22 * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
23 * OTHER DEALINGS IN THE SOFTWARE.
24 */
25
26/**
27 * @file
28 * certificate building and verification functions to use with HIP
29 */
30
31#include <regex.h>
32#include <stdio.h>
33#include <stdlib.h>
34#include <string.h>
35#include <openssl/bn.h>
36#include <openssl/conf.h>
37#include <openssl/dsa.h>
38#include <openssl/err.h>
39#include <openssl/evp.h>
40#include <openssl/rsa.h>
41#include <openssl/safestack.h>
42
43#include "crypto.h"
44#include "debug.h"
45#include "ife.h"
46#include "message.h"
47#include "prefix.h"
48#include "straddr.h"
49#include "certtools.h"
50
51/*******************************************************************************
52 * FUNCTIONS FOR SPKI *
53 *******************************************************************************/
54
55/**
56 * Function that verifies the signature in
57 * the given SPKI cert sent by the "client"
58 *
59 * @param cert points to hip_cert_spki_info that is going to be verified
60 *
61 * @return 0 if signature matches, -1 if error or signature did NOT match
62 *
63 * @note see hip_cert_spki_char2certinfo to convert from wire to hip_cert_spki_info
64 */
65int hip_cert_spki_lib_verify(struct hip_cert_spki_info *cert)
66{
67 int err = 0, start = 0, stop = 0, evpret = 0, keylen = 0, algo = 0;
68 char buf[200];
69
70 unsigned char sha_digest[21];
71 unsigned char *sha_retval;
72 unsigned char *signature_hash = NULL;
73 unsigned char *signature_hash_b64 = NULL;
74 unsigned char *signature_b64 = NULL;
75
76 unsigned char *signature = NULL;
77
78 /** RSA */
79 RSA *rsa = NULL;
80 unsigned long e_code;
81 char *e_hex = NULL;
82 unsigned char *modulus_b64 = NULL;
83 unsigned char *modulus = NULL;
84
85 /** DSA */
86 DSA *dsa = NULL;
87 unsigned char *p_bin = NULL, *q_bin = NULL, *g_bin = NULL, *y_bin = NULL;
88 unsigned char *p_b64 = NULL, *q_b64 = NULL, *g_b64 = NULL, *y_b64 = NULL;
89 DSA_SIG *dsa_sig;
90
91 /* rules for regular expressions */
92
93 /*
94 * Rule to get the info if we are using DSA
95 */
96 char dsa_rule[] = "[d][s][a][-][p][k][c][s][1][-][s][h][a][1]";
97
98 /*
99 * Rule to get the info if we are using RSA
100 */
101 char rsa_rule[] = "[r][s][a][-][p][k][c][s][1][-][s][h][a][1]";
102
103 /*
104 * Rule to get DSA p
105 * Look for pattern "(p |" and stop when first "|"
106 * anything in base 64 is accepted inbetween
107 */
108 char p_rule[] = "[(][p][ ][|][[A-Za-z0-9+/()#=-]*[|]";
109
110 /*
111 * Rule to get DSA q
112 * Look for pattern "(q |" and stop when first "|"
113 * anything in base 64 is accepted inbetween
114 */
115 char q_rule[] = "[(][q][ ][|][[A-Za-z0-9+/()#=-]*[|]";
116
117 /*
118 * Rule to get DSA g
119 * Look for pattern "(g |" and stop when first "|"
120 * anything in base 64 is accepted inbetween
121 */
122 char g_rule[] = "[(][g][ ][|][[A-Za-z0-9+/()#=-]*[|]";
123
124 /*
125 * Rule to get DSA y / pub_key
126 * Look for pattern "(y |" and stop when first "|"
127 * anything in base 64 is accepted inbetween
128 */
129 char y_rule[] = "[(][y][ ][|][[A-Za-z0-9+/()#=-]*[|]";
130
131 /*
132 * rule to get the public exponent RSA
133 * Look for the part that says # and after that some hex blob and #
134 */
135 char e_rule[] = "[#][0-9A-Fa-f]*[#]";
136
137 /*
138 * rule to get the public modulus RSA
139 * Look for the part that starts with '|' and after that anything
140 * that is in base 64 char set and then '|' again
141 */
142 char n_rule[] = "[|][A-Za-z0-9+/()#=-]*[|]";
143
144 /*
145 * rule to get the signature hash
146 * Look for the similar than the n_rule
147 */
148 char h_rule[] = "[|][A-Za-z0-9+/()#=-]*[|]";
149
150 /*
151 * rule to get the signature
152 * Look for part that starts ")|" and base 64 blob after it
153 * and stops to '|' char remember to add and subtract 2 from
154 * the indexes below
155 */
156 char s_rule[] = "[)][|][A-Za-z0-9+/()#=-]*[|]";
157
158 /* check the algo DSA or RSA */
159 HIP_DEBUG("Verifying\nRunning regexps to identify algo\n");
160 start = stop = 0;
161 algo = hip_cert_regex(dsa_rule, cert->public_key, &start, &stop);
162 if (algo != -1) {
163 HIP_DEBUG("Public-key is DSA\n");
164 algo = HIP_HI_DSA;
165 goto algo_check_done;
166 }
167 start = stop = 0;
168 algo = hip_cert_regex(rsa_rule, cert->public_key, &start, &stop);
169 if (algo != -1) {
170 HIP_DEBUG("Public-key is RSA\n");
171 algo = HIP_HI_RSA;
172 goto algo_check_done;
173 }
174 HIP_DEBUG((1 != 1), -1, "Unknown algorithm\n");
175
176algo_check_done:
177 if (algo == HIP_HI_RSA) {
178 /* malloc space for new rsa */
179 rsa = RSA_new();
180 HIP_IFEL(!rsa, -1, "Failed to malloc RSA\n");
181
182 /* extract the public-key from cert to rsa */
183
184 /* public exponent first */
185 start = stop = 0;
186 HIP_IFEL(hip_cert_regex(e_rule, cert->public_key, &start, &stop), -1,
187 "Failed to run hip_cert_regex (exponent)\n");
188 e_hex = malloc(stop - start);
189 HIP_IFEL(!e_hex, -1, "Malloc for e_hex failed\n");
190 snprintf((char *) e_hex, stop - start - 1, "%s",
191 &cert->public_key[start + 1]);
192
193 /* public modulus */
194 start = stop = 0;
195 HIP_IFEL(hip_cert_regex(n_rule, cert->public_key, &start, &stop), -1,
196 "Failed to run hip_cert_regex (modulus)\n");
197 modulus_b64 = calloc(1, stop - start + 1);
198 HIP_IFEL(!modulus_b64, -1, "calloc for modulus_b64 failed\n");
199 modulus = calloc(1, stop - start + 1);
200 HIP_IFEL(!modulus, -1, "calloc for modulus failed\n");
201 snprintf((char *) modulus_b64, stop - start - 1, "%s",
202 &cert->public_key[start + 1]);
203
204 /* put the stuff into the RSA struct */
205 BN_hex2bn(&rsa->e, e_hex);
206 evpret = EVP_DecodeBlock(modulus, modulus_b64,
207 strlen((char *) modulus_b64));
208
209 /* EVP returns a multiple of 3 octets, subtract any extra */
210 keylen = evpret;
211 if (keylen % 4 != 0) {
212 --keylen;
213 keylen = keylen - keylen % 2;
214 }
215 signature = malloc(keylen);
216 HIP_IFEL(!signature, -1, "Malloc for signature failed.\n");
217 rsa->n = BN_bin2bn(modulus, keylen, 0);
218 } else if (algo == HIP_HI_DSA) {
219 /* malloc space for new dsa */
220 dsa = DSA_new();
221 HIP_IFEL(!dsa, -1, "Failed to malloc DSA\n");
222
223 /* Extract public key from the cert */
224
225 /* dsa->p */
226 start = stop = 0;
227 HIP_IFEL(hip_cert_regex(p_rule, cert->public_key, &start, &stop), -1,
228 "Failed to run hip_cert_regex dsa->p\n");
229 p_b64 = calloc(1, stop - start + 1);
230 HIP_IFEL(!p_b64, -1, "calloc for p_b64 failed\n");
231 p_bin = calloc(1, stop - start + 1);
232 HIP_IFEL(!p_bin, -1, "calloc for p_bin failed\n");
233 snprintf((char *) p_b64, stop - start - 1, "%s",
234 &cert->public_key[start + 1]);
235 evpret = EVP_DecodeBlock(p_bin, p_b64, strlen((char *) p_b64));
236
237 /* dsa->q */
238 start = stop = 0;
239 HIP_IFEL(hip_cert_regex(q_rule, cert->public_key, &start, &stop), -1,
240 "Failed to run hip_cert_regex dsa->q\n");
241 q_b64 = calloc(1, stop - start + 1);
242 HIP_IFEL(!q_b64, -1, "calloc for q_b64 failed\n");
243 q_bin = calloc(1, stop - start + 1);
244 HIP_IFEL(!q_bin, -1, "calloc for q_bin failed\n");
245 snprintf((char *) q_b64, stop - start - 1, "%s",
246 &cert->public_key[start + 1]);
247 evpret = EVP_DecodeBlock(q_bin, q_b64, strlen((char *) q_b64));
248
249 /* dsa->g */
250 start = stop = 0;
251 HIP_IFEL(hip_cert_regex(g_rule, cert->public_key, &start, &stop), -1,
252 "Failed to run hip_cert_regex dsa->g\n");
253 g_b64 = calloc(1, stop - start + 1);
254 HIP_IFEL(!g_b64, -1, "calloc for g_b64 failed\n");
255 g_bin = calloc(1, stop - start + 1);
256 HIP_IFEL(!g_bin, -1, "calloc for g_bin failed\n");
257 snprintf((char *) g_b64, stop - start - 1, "%s",
258 &cert->public_key[start + 1]);
259 evpret = EVP_DecodeBlock(g_bin, g_b64, strlen((char *) g_b64));
260
261 /* dsa->y */
262 start = stop = 0;
263 HIP_IFEL(hip_cert_regex(y_rule, cert->public_key, &start, &stop), -1,
264 "Failed to run hip_cert_regex dsa->y\n");
265 y_b64 = calloc(1, stop - start + 1);
266 HIP_IFEL(!y_b64, -1, "calloc for y_b64 failed\n");
267 y_bin = calloc(1, stop - start + 1);
268 HIP_IFEL(!y_bin, -1, "calloc for y_bin failed\n");
269 snprintf((char *) y_b64, stop - start - 1, "%s",
270 &cert->public_key[start + 1]);
271 evpret = EVP_DecodeBlock(y_bin, y_b64, strlen((char *) y_b64));
272 } else if (algo == HIP_HI_ECDSA) {
273 HIP_OUT_ERR(-1, "Call to unimplemented ECDSA case.\n");
274 } else {
275 HIP_OUT_ERR(-1, "Unknown algorithm\n");
276 }
277
278 /* build sha1 digest that will be signed */
279 HIP_IFEL(!(sha_retval = SHA1((unsigned char *) cert->cert,
280 strlen((char *) cert->cert), sha_digest)),
281 -1, "SHA1 error when creating digest.\n");
282
283 /* Get the signature hash and compare it to the sha_digest we just made */
284 start = stop = 0;
285 HIP_IFEL(hip_cert_regex(h_rule, cert->signature, &start, &stop), -1,
286 "Failed to run hip_cert_regex (signature hash)\n");
287 signature_hash_b64 = calloc(1, stop - start + 1);
288 HIP_IFEL(!signature_hash_b64, -1, "Failed to calloc signature_hash_b64\n");
289 signature_hash = malloc(stop - start + 1);
290 HIP_IFEL(!signature_hash, -1, "Failed to malloc signature_hash\n");
291 snprintf((char *) signature_hash_b64, stop - start - 1, "%s",
292 &cert->signature[start + 1]);
293 evpret = EVP_DecodeBlock(signature_hash, signature_hash_b64,
294 strlen((char *) signature_hash_b64));
295 HIP_IFEL(memcmp(sha_digest, signature_hash, 20), -1,
296 "Signature hash did not match of the one made from the"
297 "cert sequence in the certificate\n");
298
299 /* memset signature and put it into its place */
300 start = stop = 0;
301 HIP_IFEL(hip_cert_regex(s_rule, cert->signature, &start, &stop), -1,
302 "Failed to run hip_cert_regex (signature)\n");
303 signature_b64 = calloc(1, stop - start + 1);
304 HIP_IFEL(!signature_b64, -1, "Failed to calloc signature_b64\n");
305 snprintf((char *) signature_b64, stop - start - 2, "%s",
306 &cert->signature[start + 2]);
307 if (algo == HIP_HI_DSA) {
308 signature = malloc(stop - start + 1);
309 HIP_IFEL(!signature, -1, "Failed to malloc signature (dsa)\n");
310 }
311 evpret = EVP_DecodeBlock(signature, signature_b64,
312 strlen((char *) signature_b64));
313
314 if (algo == HIP_HI_RSA) {
315 /* do the verification */
316 err = RSA_verify(NID_sha1, sha_digest, SHA_DIGEST_LENGTH,
317 signature, RSA_size(rsa), rsa);
318 e_code = ERR_get_error();
319 ERR_load_crypto_strings();
320 ERR_error_string(e_code, buf);
321
322 /* RSA_verify returns 1 if success. */
323 cert->success = err == 1 ? 0 : -1;
324 HIP_IFEL((err = err == 1 ? 0 : -1), -1, "RSA_verify error\n");
325 } else if (algo == HIP_HI_DSA) {
326 /* build the signature structure */
327 dsa_sig = DSA_SIG_new();
328 HIP_IFEL(!dsa_sig, 1, "Failed to allocate DSA_SIG\n");
329 dsa_sig->r = BN_bin2bn(&signature[1], DSA_PRIV, NULL);
330 dsa_sig->s = BN_bin2bn(&signature[1 + DSA_PRIV], DSA_PRIV, NULL);
331
332 /* verify the DSA signature */
333 err = DSA_do_verify(sha_digest, SHA_DIGEST_LENGTH,
334 dsa_sig, dsa) == 0 ? 1 : 0;
335
336 /* DSA_do_verify returns 1 if success. */
337 cert->success = err == 1 ? 0 : -1;
338 HIP_IFEL((err = err == 1 ? 0 : -1), -1, "DSA_do_verify error\n");
339 } else if (algo == HIP_HI_ECDSA) {
340 HIP_OUT_ERR(-1, "Call to unimplemented ECDSA case.\n");
341 } else {
342 HIP_OUT_ERR(-1, "Unknown algorithm\n");
343 }
344
345out_err:
346 free(signature_hash_b64);
347 free(signature_hash);
348 free(modulus_b64);
349 free(modulus);
350 free(e_hex);
351 RSA_free(rsa);
352 DSA_free(dsa);
353 return err;
354}
355
356/**
357 * Function to build the basic cert object of SPKI clears public-key
358 * object and signature in hip_cert_spki_header
359 *
360 * @param minimal_content holds the struct hip_cert_spki_header
361 * containing the minimal needed information for
362 * cert object, also contains the char table where
363 * the cert object is to be stored
364 *
365 * @return always 0
366 */
367static int cert_spki_build_cert(struct hip_cert_spki_info *minimal_content)
368{
369 char needed[] = "(cert )";
370 memset(minimal_content->public_key, '\0', sizeof(minimal_content->public_key));
371 memset(minimal_content->cert, '\0', sizeof(minimal_content->cert));
372 memset(minimal_content->signature, '\0', sizeof(minimal_content->signature));
373 sprintf(minimal_content->cert, "%s", needed);
374
375 return 0;
376}
377
378/**
379 * Function for injecting objects to cert object
380 *
381 * @param to hip_cert_spki_info containing the char table where to insert
382 * @param after is a char pointer for the regcomp after which the inject happens
383 * @param what is char pointer of what to
384 *
385 * @return 0 if ok and negative if error. -1 returned for example when after is NOT found
386 */
387static int cert_spki_inject(struct hip_cert_spki_info *to,
388 const char *after, const char *what)
389{
390 int err = 0, status = 0;
391 regex_t re;
392 regmatch_t pm[1];
393 char *tmp_cert;
394
395 tmp_cert = calloc(1, strlen(to->cert) + strlen(what) + 1);
396 if (!tmp_cert) {
397 return -ENOMEM;
398 }
399 /* Compiling the regular expression */
400 HIP_IFEL(regcomp(&re, after, REG_EXTENDED), -1,
401 "Compilation of the regular expression failed\n");
402 /* Running the regular expression */
403 HIP_IFEL((status = regexec(&re, to->cert, 1, pm, 0)), -1,
404 "Handling of regular expression failed\n");
405 /* Using tmp char table to do the inject (remember the terminators)
406 * first the beginning */
407 snprintf(tmp_cert, pm[0].rm_eo + 2, "%s", to->cert);
408 /* Then the middle part to be injected */
409 snprintf(&tmp_cert[pm[0].rm_eo + 1], strlen(what) + 1, "%s", what);
410 /* then glue back the rest of the original at the end */
411 snprintf(&tmp_cert[(pm[0].rm_eo + strlen(what) + 1)],
412 (strlen(to->cert) - pm[0].rm_eo), "%s", &to->cert[pm[0].rm_eo + 1]);
413 /* move tmp to the result */
414 sprintf(to->cert, "%s", tmp_cert);
415out_err:
416 free(tmp_cert);
417 regfree(&re);
418 return err;
419}
420
421/**
422 * Function to build the create minimal SPKI cert (plus socket parameter)
423 *
424 * @param content holds the struct hip_cert_spki_info containing
425 * the minimal needed information for cert object,
426 * also contains the char table where the cert object
427 * is to be stored
428 * @param issuer_type With HIP its HIT
429 * @param issuer HIT in representation encoding 2001:001...
430 * @param subject_type With HIP its HIT
431 * @param subject HIT in representation encoding 2001:001...
432 * @param not_before time in timeval before which the cert should not be used
433 * @param not_after time in timeval after which the cert should not be used
434 * @param hip_user_socket socket, already connected to hipd, to pass through to
435 * hip_send_recv_daemon_info
436 * @return 0 if ok -1 if error
437 */
438static int cert_spki_create_cert_sock(struct hip_cert_spki_info *content,
439 const char *issuer_type,
440 struct in6_addr *issuer,
441 const char *subject_type,
442 struct in6_addr *subject,
443 time_t *not_before,
444 time_t *not_after,
445 int hip_user_socket)
446{
447 int err = 0;
448 char *tmp_issuer = NULL;
449 char *tmp_subject = NULL;
450 char *tmp_before = NULL;
451 char *tmp_after = NULL;
452 struct tm *ts = NULL;
453 char buf_before[80];
454 char buf_after[80];
455 char present_issuer[41] = { 0 };
456 char present_subject[41] = { 0 };
457 struct hip_common *msg = NULL;
458 const struct hip_cert_spki_info *returned = NULL;
459
460 /* Malloc needed */
461 tmp_issuer = calloc(1, 128);
462 if (!tmp_issuer) {
463 goto out_err; /* Why does this return 0? */
464 }
465 tmp_subject = calloc(1, 128);
466 if (!tmp_subject) {
467 goto out_err;
468 }
469 tmp_before = calloc(1, 128);
470 if (!tmp_before) {
471 goto out_err;
472 }
473 tmp_after = calloc(1, 128);
474 if (!tmp_after) {
475 goto out_err;
476 }
477 HIP_IFEL(!(msg = malloc(HIP_MAX_PACKET)), -1,
478 "Malloc for msg failed\n");
479
480 /* Make needed transforms to the date */
481 /* Format and print the time, "yyyy-mm-dd hh:mm:ss"
482 * (not-after "1998-04-15_00:00:00") */
483 ts = localtime(not_before);
484 strftime(buf_before, sizeof(buf_before), "%Y-%m-%d_%H:%M:%S", ts);
485 ts = localtime(not_after);
486 strftime(buf_after, sizeof(buf_after), "%Y-%m-%d_%H:%M:%S", ts);
487
488 sprintf(tmp_before, "(not-before \"%s\")", buf_before);
489 sprintf(tmp_after, "(not-after \"%s\")", buf_after);
490
491 ipv6_addr_copy(&content->issuer_hit, issuer);
492 inet_ntop(AF_INET6, issuer, present_issuer, INET6_ADDRSTRLEN);
493 inet_ntop(AF_INET6, subject, present_subject, INET6_ADDRSTRLEN);
494
495 sprintf(tmp_issuer, "(hash %s %s)", issuer_type, present_issuer);
496 sprintf(tmp_subject, "(hash %s %s)", subject_type, present_subject);
497
498 /* Create the cert sequence */
499 HIP_IFEL(cert_spki_build_cert(content), -1,
500 "cert_spki_build_cert failed\n");
501
502 HIP_IFEL(cert_spki_inject(content, "cert", tmp_after), -1,
503 "cert_spki_inject failed to inject\n");
504 HIP_IFEL(cert_spki_inject(content, "cert", tmp_before), -1,
505 "cert_spki_inject failed to inject\n");
506 HIP_IFEL(cert_spki_inject(content, "cert", "(subject )"), -1,
507 "cert_spki_inject failed to inject\n");
508 HIP_IFEL(cert_spki_inject(content, "subject", tmp_subject), -1,
509 "cert_spki_inject failed to inject\n");
510 HIP_IFEL(cert_spki_inject(content, "cert", "(issuer )"), -1,
511 "cert_spki_inject failed to inject\n");
512 HIP_IFEL(cert_spki_inject(content, "issuer", tmp_issuer), -1,
513 "cert_spki_inject failed to inject\n");
514
515 /* Create the signature and the public-key sequences */
516
517 /* Send the daemon the struct hip_cert_spki_header
518 * containing the cert sequence in content->cert.
519 * As a result you should get the struct back with
520 * public-key and signature fields filled */
521
522 /* build the msg to be sent to the daemon */
523 hip_msg_init(msg);
524 HIP_IFEL(hip_build_user_hdr(msg, HIP_MSG_CERT_SPKI_SIGN, 0), -1,
525 "Failed to build user header\n");
526 HIP_IFEL(hip_build_param_cert_spki_info(msg, content), -1,
527 "Failed to build cert_info\n");
528 /* send and wait */
529 HIP_DEBUG("Sending request to sign SPKI cert sequence to "
530 "daemon and waiting for answer\n");
531 hip_send_recv_daemon_info(msg, 0, hip_user_socket);
532
533 /* get the struct from the message sent back by the daemon */
534 HIP_IFEL(!(returned = hip_get_param(msg, HIP_PARAM_CERT_SPKI_INFO)),
535 -1, "No hip_cert_spki_info struct found from daemons msg\n");
536
537 memcpy(content, returned, sizeof(struct hip_cert_spki_info));
538
539out_err:
540 /* free everything malloced */
541 free(tmp_before);
542 free(tmp_after);
543 free(tmp_issuer);
544 free(tmp_subject);
545 free(msg);
546 return err;
547}
548
549/**
550 * Function to build the create minimal SPKI cert
551 *
552 * @param content holds the struct hip_cert_spki_info containing
553 * the minimal needed information for cert object,
554 * also contains the char table where the cert object
555 * is to be stored
556 * @param issuer_type With HIP its HIT
557 * @param issuer HIT in representation encoding 2001:001...
558 * @param subject_type With HIP its HIT
559 * @param subject HIT in representation encoding 2001:001...
560 * @param not_before time in timeval before which the cert should not be used
561 * @param not_after time in timeval after which the cert should not be used
562 * @return 0 if ok -1 if error
563 */
564int hip_cert_spki_create_cert(struct hip_cert_spki_info *content,
565 const char *issuer_type, struct in6_addr *issuer,
566 const char *subject_type, struct in6_addr *subject,
567 time_t *not_before, time_t *not_after)
568{
569 return cert_spki_create_cert_sock(content, issuer_type, issuer,
570 subject_type, subject, not_before,
571 not_after, 0);
572}
573
574/**
575 * Function that takes the cert in single char table and constructs
576 * hip_cert_spki_info from it
577 *
578 * @param from char pointer to the whole certificate
579 * @param to hip_cert_spki_info containing the char table where to insert
580 *
581 * @return 0 if ok and negative if error.
582 */
583int hip_cert_spki_char2certinfo(char *from, struct hip_cert_spki_info *to)
584{
585 int start = 0, stop = 0;
586 /*
587 * p_rule looks for string "(public_key " after which there can be
588 * pretty much anything until string "|)))" is encountered.
589 * This is the public-key sequence.
590 */
591 char p_rule[] = "[(]public_key [ A-Za-z0-9+|/()#=-]*[|][)][)][)]";
592 /*
593 * c_rule looks for string "(cert " after which there can be
594 * pretty much anything until string '"))' is encountered.
595 * This is the cert sequence.
596 */
597 char c_rule[] = "[(]cert [ A-Za-z0-9+|/():=_\"-]*[\"][)][)]"; //\" is one char
598 /*
599 * s_rule looks for string "(signature " after which there can be
600 * pretty much anything until string "|))" is encountered.
601 * This is the signature sequence.
602 */
603 char s_rule[] = "[(]signature [ A-Za-z0-9+/|()=]*[|][)][)]";
604
605 /* Look for the public key */
606 if (hip_cert_regex(p_rule, from, &start, &stop)) {
607 HIP_ERROR("Failed to run hip_cert_regex (public-key)\n");
608 return -1;
609 }
610 snprintf(to->public_key, stop - start + 1, "%s", &from[start]);
611
612 /* Look for the cert sequence */
613 start = stop = 0;
614 if (hip_cert_regex(c_rule, from, &start, &stop)) {
615 HIP_ERROR("Failed to run hip_cert_regex (cert)\n");
616 return -1;
617 }
618 snprintf(to->cert, stop - start + 1, "%s", &from[start]);
619
620 /* look for the signature sequence */
621 start = stop = 0;
622 if (hip_cert_regex(s_rule, from, &start, &stop)) {
623 HIP_ERROR("Failed to run hip_cert_regex (signature)\n");
624 return -1;
625 }
626 snprintf(to->signature, stop - start + 1, "%s", &from[start]);
627
628 return 0;
629}
630
631/**
632 * Function that sends the given hip_cert_spki_info to the daemon to
633 * verification
634 *
635 * @param to_verification is the cert to be verified
636 *
637 * @return 0 if ok and negative if error or unsuccessful.
638 *
639 * @note use hip_cert_spki_char2certinfo to build the hip_cert_spki_info
640 */
641int hip_cert_spki_send_to_verification(struct hip_cert_spki_info *to_verification)
642{
643 int err = 0;
644 struct hip_common *msg;
645 const struct hip_cert_spki_info *returned;
646
647 if (!(msg = malloc(HIP_MAX_PACKET))) {
648 HIP_ERROR("Malloc for msg failed\n");
649 return -ENOMEM;
650 }
651 hip_msg_init(msg);
652 /* build the msg to be sent to the daemon */
653 HIP_IFEL(hip_build_user_hdr(msg, HIP_MSG_CERT_SPKI_VERIFY, 0), -1,
654 "Failed to build user header\n");
655 HIP_IFEL(hip_build_param_cert_spki_info(msg, to_verification), -1,
656 "Failed to build cert_info\n");
657
658 /* send and wait */
659 HIP_DEBUG("Sending request to verify SPKI cert to "
660 "daemon and waiting for answer\n");
661 hip_send_recv_daemon_info(msg, 0, 0);
662
663 HIP_IFEL(!(returned = hip_get_param(msg, HIP_PARAM_CERT_SPKI_INFO)),
664 -1, "No hip_cert_spki_info struct found from daemons msg\n");
665
666 memcpy(to_verification, returned, sizeof(struct hip_cert_spki_info));
667
668out_err:
669 free(msg);
670 return err;
671}
672
673/******************************************************************************
674 * FUNCTIONS FOR x509v3 *
675 ******************************************************************************/
676
677/**
678 * Function that requests for a certificate from daemon and gives it back.
679 *
680 * @param subject is the subjects HIT
681 *
682 * @param certificate is pointer to a buffer to which this function writes the completed cert
683 *
684 * @return positive on success negative otherwise
685 *
686 * @note The certificate is given in DER encoding
687 */
688int hip_cert_x509v3_request_certificate(struct in6_addr *subject,
689 unsigned char *certificate)
690{
691 int err = 0;
692 struct hip_common *msg;
693 const struct hip_cert_x509_resp *p;
694
695 if (!(msg = malloc(HIP_MAX_PACKET))) {
696 HIP_ERROR("Malloc for msg failed\n");
697 return -ENOMEM;
698 }
699 hip_msg_init(msg);
700 /* build the msg to be sent to the daemon */
701
702 HIP_IFEL(hip_build_user_hdr(msg, HIP_MSG_CERT_X509V3_SIGN, 0), -1,
703 "Failed to build user header\n");
704 HIP_IFEL(hip_build_param_cert_x509_req(msg, subject), -1,
705 "Failed to build cert_info\n");
706 /* send and wait */
707 HIP_DEBUG("Sending request to sign x509 cert to "
708 "daemon and waiting for answer\n");
709 hip_send_recv_daemon_info(msg, 0, 0);
710 /* get the struct from the message sent back by the daemon */
711 HIP_IFEL(!(p = hip_get_param(msg, HIP_PARAM_CERT_X509_RESP)), -1,
712 "No name x509 struct found\n");
713 memcpy(certificate, p->der, p->der_len);
714 err = p->der_len;
715
716out_err:
717 free(msg);
718 return err;
719}
720
721/**
722 * Function that requests for a verification of a certificate from
723 * daemon and tells the result.
724 *
725 * @param certificate is pointer to a certificate to be verified
726 * @param len is the length of the cert in certificate parameter in bytes
727 *
728 * @return 0 on success negative otherwise
729 *
730 * @note give the certificate in PEM encoding
731 */
732int hip_cert_x509v3_request_verification(unsigned char *certificate, int len)
733{
734 int err = 0;
735 struct hip_common *msg;
736 const struct hip_cert_x509_resp *received;
737
738 if (!(msg = malloc(HIP_MAX_PACKET))) {
739 HIP_ERROR("Malloc for msg failed\n");
740 return -ENOMEM;
741 }
742 hip_msg_init(msg);
743
744 /* build the msg to be sent to the daemon */
745 HIP_IFEL(hip_build_user_hdr(msg, HIP_MSG_CERT_X509V3_VERIFY, 0), -1,
746 "Failed to build user header\n");
747 HIP_IFEL(hip_build_param_cert_x509_ver(msg, (char *) certificate, len), -1,
748 "Failed to build cert_info\n");
749
750 /* send and wait */
751 HIP_DEBUG("Sending request to verify x509 cert to "
752 "daemon and waiting for answer\n");
753 hip_send_recv_daemon_info(msg, 0, 0);
754
755 /* get the struct from the message sent back by the daemon */
756 HIP_IFEL(!(received = hip_get_param(msg, HIP_PARAM_CERT_X509_RESP)), -1,
757 "No x509 struct found\n");
758 err = hip_get_msg_err(msg);
759 if (err == 0) {
760 HIP_DEBUG("Verified successfully\n");
761 } else {
762 HIP_DEBUG("Verification failed\n");
763 }
764
765out_err:
766 free(msg);
767 return err;
768}
769
770/*****************************************************************************
771 * UTILITY FUNCTIONS *
772 *****************************************************************************/
773
774/**
775 * Read configuration section from loaded configuration file.
776 *
777 * @param section_name the name of the section to be retrieved
778 * @param conf the loaded configuration to read from
779 *
780 * @return STACK_OF(CONF_VALUE) pointer if OK, NULL on error
781 *
782 * @note Remember to open the configuration file with hip_cert_open_conf() and
783 * close it after processing with NCONF_free().
784 */
785STACK_OF(CONF_VALUE) *hip_read_conf_section(const char *section_name,
786 CONF *conf)
787{
788 STACK_OF(CONF_VALUE) *sec;
789
790 if (!(sec = NCONF_get_section(conf, section_name))) {
791 HIP_ERROR("Section %s was not in the configuration (%s)\n",
792 section_name, HIP_CERT_CONF_PATH);
793 return NULL;
794 }
795
796 return sec;
797}
798
799/**
800 * Load a configuration file from HIP_CERT_CONF_PATH.
801 *
802 * @return CONF pointer if OK, NULL on error
803 */
804CONF *hip_open_conf(const char *filename)
805{
806 long err;
807 CONF *conf;
808
809 conf = NCONF_new(NCONF_default());
810 if (!NCONF_load(conf, filename, &err)) {
811 HIP_ERROR("Error opening the configuration file");
812 return NULL;
813 }
814 return conf;
815}
816
817/**
818 * Function that wraps regular expression stuff and gives the answer :)
819 *
820 * @param what is a char pointer to the rule used in the search (POSIX)
821 * @param from where are we looking for it char pointer
822 * @param start will store the start point of the found substr
823 * @param stop will store the end point of the found substr
824 *
825 * @return 0 if ok and negative if error.
826 *
827 * @note Be carefull with the what so you get what you want :)
828 */
829int hip_cert_regex(char *what, char *from, int *start, int *stop)
830{
831 int err = 0, status = 0;
832 regex_t re;
833 regmatch_t answer[1];
834
835 *start = *stop = 0;
836
837 /* Compiling the regular expression */
838 if (regcomp(&re, what, REG_EXTENDED)) {
839 HIP_ERROR("Compilation of the regular expression failed\n");
840 return -1;
841 }
842 /* Running the regular expression */
843 // TODO this might need to be an error!?
844 // this needs to be separated to found, not found, and error -Samu
845 if ((status = regexec(&re, from, 1, answer, 0))) {
846 err = -1;
847 goto out_err;
848 }
849
850 *start = answer[0].rm_so;
851 *stop = answer[0].rm_eo;
852
853out_err:
854 regfree(&re);
855 return err;
856}
8570
=== removed file 'lib/core/certtools.h'
--- lib/core/certtools.h 2012-01-14 15:29:47 +0000
+++ lib/core/certtools.h 1970-01-01 00:00:00 +0000
@@ -1,79 +0,0 @@
1/*
2 * Copyright (c) 2010 Aalto University and RWTH Aachen University.
3 *
4 * Permission is hereby granted, free of charge, to any person
5 * obtaining a copy of this software and associated documentation
6 * files (the "Software"), to deal in the Software without
7 * restriction, including without limitation the rights to use,
8 * copy, modify, merge, publish, distribute, sublicense, and/or sell
9 * copies of the Software, and to permit persons to whom the
10 * Software is furnished to do so, subject to the following
11 * conditions:
12 *
13 * The above copyright notice and this permission notice shall be
14 * included in all copies or substantial portions of the Software.
15 *
16 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
17 * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
18 * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
19 * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
20 * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
21 * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
22 * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
23 * OTHER DEALINGS IN THE SOFTWARE.
24 */
25
26/**
27 * @file
28 * Certificate building, parseing and verification functions.
29 */
30
31#ifndef HIPL_LIB_CORE_CERTTOOLS_H
32#define HIPL_LIB_CORE_CERTTOOLS_H
33
34#include <stdint.h>
35#include <netinet/in.h>
36#include <openssl/rsa.h>
37#include <openssl/ossl_typ.h>
38#include <sys/types.h>
39
40#include "protodefs.h"
41
42
43/** Defines */
44#define HIP_CERT_CONF_PATH HIPL_SYSCONFDIR "/hip_cert.conf"
45
46#define HIP_CERT_DAY 86400
47
48/** Struct used to deliver the minimal needed information to build SPKI cert */
49struct hip_cert_spki_info {
50 hip_tlv type;
51 hip_tlv_len length;
52 char public_key[768];
53 char cert[224];
54 char signature[768];
55 struct in6_addr issuer_hit;
56 /* 0 if successfully verified otherwise negative */
57 uint32_t success;
58};
59
60/** SPKI cert related functions */
61int hip_cert_spki_lib_verify(struct hip_cert_spki_info *);
62int hip_cert_spki_create_cert(struct hip_cert_spki_info *,
63 const char *, struct in6_addr *,
64 const char *, struct in6_addr *,
65 time_t *, time_t *);
66int hip_cert_spki_char2certinfo(char *, struct hip_cert_spki_info *);
67int hip_cert_spki_send_to_verification(struct hip_cert_spki_info *);
68
69/* x509v3 cert related functions */
70int hip_cert_x509v3_request_certificate(struct in6_addr *, unsigned char *);
71int hip_cert_x509v3_request_verification(unsigned char *, int);
72
73/** utility functions */
74STACK_OF(CONF_VALUE) *hip_read_conf_section(const char *section_name,
75 CONF *conf);
76CONF *hip_open_conf(const char *filename);
77int hip_cert_regex(char *, char *, int *, int *);
78
79#endif /* HIPL_LIB_CORE_CERTTOOLS_H */
800
=== removed file 'test/certteststub.c'
--- test/certteststub.c 2012-01-14 15:29:47 +0000
+++ test/certteststub.c 1970-01-01 00:00:00 +0000
@@ -1,196 +0,0 @@
1/*
2 * Copyright (c) 2010 Aalto University and RWTH Aachen University.
3 *
4 * Permission is hereby granted, free of charge, to any person
5 * obtaining a copy of this software and associated documentation
6 * files (the "Software"), to deal in the Software without
7 * restriction, including without limitation the rights to use,
8 * copy, modify, merge, publish, distribute, sublicense, and/or sell
9 * copies of the Software, and to permit persons to whom the
10 * Software is furnished to do so, subject to the following
11 * conditions:
12 *
13 * The above copyright notice and this permission notice shall be
14 * included in all copies or substantial portions of the Software.
15 *
16 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
17 * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
18 * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
19 * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
20 * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
21 * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
22 * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
23 * OTHER DEALINGS IN THE SOFTWARE.
24 */
25
26/**
27 * @file
28 * A teststub for certtools.c/h
29 *
30 * File for testing the main operations of certtools.
31 * First this test takes the default HIT and the corresponding key.
32 * Secondly it creates a certificate where itself is the issuer and the subject.
33 * Then it tries to verify it. If it succeeds everything should be OK :)
34 */
35
36#include <stdio.h>
37#include <stdlib.h>
38#include <string.h>
39#include <time.h>
40#include <arpa/inet.h>
41#include <openssl/conf.h>
42#include <openssl/ossl_typ.h>
43#include <openssl/safestack.h>
44
45#include "lib/core/certtools.h"
46#include "lib/core/debug.h"
47#include "lib/core/ife.h"
48#include "lib/core/protodefs.h"
49
50
51int main(int argc, char *argv[])
52{
53 int err = 0, i = 0, len;
54 struct hip_cert_spki_info *cert = NULL;
55 struct hip_cert_spki_info *to_verification = NULL;
56 time_t not_before = 0, not_after = 0;
57 struct hip_common *msg;
58 struct in6_addr *defhit;
59 char certificate[1024];
60 unsigned char der_cert[1024];
61 CONF *conf;
62 CONF_VALUE *item;
63 STACK_OF(CONF_VALUE) *sec = NULL;
64 STACK_OF(CONF_VALUE) *sec_name = NULL;
65
66 if (argc != 2) {
67 printf("Usage: %s spki|x509\n", argv[0]);
68 exit(EXIT_SUCCESS);
69 }
70
71 HIP_DEBUG("- This test tool has to be run as root otherwise this will fail!\n");
72 HIP_DEBUG("- Hipd has to run otherwise this will hang!\n");
73
74 HIP_IFEL(!(msg = malloc(HIP_MAX_PACKET)), -1,
75 "Malloc for msg failed\n");
76 defhit = malloc(sizeof(struct in6_addr));
77 if (!defhit) {
78 goto out_err;
79 }
80
81 if (strcmp(argv[1], "spki")) {
82 goto skip_spki;
83 }
84
85 HIP_DEBUG("Starting to test SPKI certficate tools\n");
86
87 cert = malloc(sizeof(struct hip_cert_spki_info));
88 if (!cert) {
89 goto out_err;
90 }
91
92 to_verification = malloc(sizeof(struct hip_cert_spki_info));
93 if (!to_verification) {
94 goto out_err;
95 }
96
97 time(&not_before);
98 time(&not_after);
99 HIP_DEBUG("Reading configuration file (%s)\n", HIP_CERT_CONF_PATH);
100 conf = hip_open_conf(HIP_CERT_CONF_PATH);
101 sec = hip_read_conf_section("hip_spki", conf);
102
103 for (i = 0; i < sk_CONF_VALUE_num(sec); i++) {
104 item = sk_CONF_VALUE_value(sec, i);
105 if (!strcmp(item->name, "issuerhit")) {
106 err = inet_pton(AF_INET6, item->value, defhit);
107 if (err < 1) {
108 err = -1;
109 goto out_err;
110 }
111 }
112 if (!strcmp(item->name, "days")) {
113 not_after += HIP_CERT_DAY * atoi(item->value);
114 }
115 }
116 NCONF_free(conf);
117
118 hip_cert_spki_create_cert(cert,
119 "hit", defhit,
120 "hit", defhit,
121 &not_before,