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
1=== modified file 'Makefile.am'
2--- Makefile.am 2012-02-13 11:20:22 +0000
3+++ Makefile.am 2012-02-20 21:55:24 +0000
4@@ -35,11 +35,9 @@
5 EXTRA_DIST += $(wildcard $(addprefix $(srcdir)/tools/,*.cfg *.pl *.sh *.xml))
6 EXTRA_DIST += $(wildcard $(addprefix $(srcdir)/hipfw/,*.cfg))
7 EXTRA_DIST += $(HIPL_HEADER_LIST)
8-EXTRA_DIST += hipd/pisa.c hipfw/pisa.c hipfw/pisa_cert.c
9
10 ### user programs ###
11 bin_PROGRAMS = test/auth_performance \
12- test/certteststub \
13 test/hc_performance
14
15 if HIP_PERFORMANCE
16@@ -49,8 +47,7 @@
17
18 ### superuser programs ###
19 sbin_PROGRAMS = hipd/hipd \
20- tools/hipconf \
21- tools/pisacert
22+ tools/hipconf
23
24 if HIP_FIREWALL
25 sbin_PROGRAMS += hipfw/hipfw
26@@ -84,7 +81,6 @@
27 ### source declarations ###
28
29 test_auth_performance_SOURCES = test/auth_performance.c
30-test_certteststub_SOURCES = test/certteststub.c
31 test_dh_performance_SOURCES = test/dh_performance.c
32 test_fw_port_bindings_performance_SOURCES = hipfw/file_buffer.c \
33 hipfw/line_parser.c \
34@@ -93,10 +89,8 @@
35 test_hc_performance_SOURCES = test/hc_performance.c
36
37 tools_hipconf_SOURCES = tools/hipconf.c
38-tools_pisacert_SOURCES = tools/pisacert.c
39
40 hipd_hipd_sources = hipd/accessor.c \
41- hipd/cert.c \
42 hipd/close.c \
43 hipd/configfilereader.c \
44 hipd/cookie.c \
45@@ -175,7 +169,6 @@
46
47 lib_core_libhipcore_la_SOURCES = lib/core/builder.c \
48 lib/core/capability.c \
49- lib/core/certtools.c \
50 lib/core/conf.c \
51 lib/core/crypto.c \
52 lib/core/debug.c \
53@@ -251,12 +244,10 @@
54 test_check_lib_core_LDADD = lib/core/libhipcore.la
55 test_check_lib_tool_LDADD = lib/core/libhipcore.la
56 test_check_modules_midauth_LDADD = lib/core/libhipcore.la
57-test_certteststub_LDADD = lib/core/libhipcore.la
58 test_dh_performance_LDADD = lib/core/libhipcore.la
59 test_fw_port_bindings_performance_LDADD = lib/core/libhipcore.la
60 test_hc_performance_LDADD = lib/core/libhipcore.la
61 tools_hipconf_LDADD = lib/core/libhipcore.la
62-tools_pisacert_LDADD = lib/core/libhipcore.la
63
64 ### dynamic library dependencies ###
65
66
67=== removed file 'hipd/cert.c'
68--- hipd/cert.c 2012-01-16 22:12:49 +0000
69+++ hipd/cert.c 1970-01-01 00:00:00 +0000
70@@ -1,1029 +0,0 @@
71-/*
72- * Copyright (c) 2010-2012 Aalto University and RWTH Aachen University.
73- *
74- * Permission is hereby granted, free of charge, to any person
75- * obtaining a copy of this software and associated documentation
76- * files (the "Software"), to deal in the Software without
77- * restriction, including without limitation the rights to use,
78- * copy, modify, merge, publish, distribute, sublicense, and/or sell
79- * copies of the Software, and to permit persons to whom the
80- * Software is furnished to do so, subject to the following
81- * conditions:
82- *
83- * The above copyright notice and this permission notice shall be
84- * included in all copies or substantial portions of the Software.
85- *
86- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
87- * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
88- * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
89- * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
90- * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
91- * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
92- * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
93- * OTHER DEALINGS IN THE SOFTWARE.
94- */
95-
96-/**
97- * @file
98- *
99- * This file defines the certificate signing and verification
100- * functions to use with HIP
101- */
102-
103-#include <errno.h>
104-#include <stdint.h>
105-#include <stdio.h>
106-#include <stdlib.h>
107-#include <string.h>
108-#include <arpa/inet.h>
109-#include <openssl/conf.h>
110-#include <openssl/dsa.h>
111-#include <openssl/err.h>
112-#include <openssl/evp.h>
113-#include <openssl/rsa.h>
114-#include <openssl/x509.h>
115-#include <openssl/x509v3.h>
116-
117-#include "lib/core/builder.h"
118-#include "lib/core/certtools.h"
119-#include "lib/core/common.h"
120-#include "lib/core/crypto.h"
121-#include "lib/core/debug.h"
122-#include "lib/core/ife.h"
123-#include "lib/core/protodefs.h"
124-#include "lib/core/straddr.h"
125-#include "lib/tool/pk.h"
126-#include "hidb.h"
127-#include "cert.h"
128-
129-
130-/****************************************************************************
131- *
132- * SPKI
133- *
134- ***************************************************************************/
135-
136-/**
137- * Function that signs the cert sequence and creates the public key
138- * sequence and the signature sequence
139- *
140- * @param msg points to the msg gotten from "client" that should
141- * contain HIP_PARAM_CERT_SPKI_INFO
142- *
143- * @return 0 if signature was created without errors, negative value
144- * is returned on errors
145- */
146-int hip_cert_spki_sign(struct hip_common *msg)
147-{
148- int err = 0, sig_len = 0, algo = 0, t = 0;
149- const struct hip_cert_spki_info *p_cert;
150- struct hip_cert_spki_info *cert;
151- struct hip_host_id *host_id = NULL;
152- unsigned char sha_digest[SHA_DIGEST_LENGTH];
153- unsigned char *signature_b64 = NULL;
154- unsigned char *digest_b64 = NULL;
155- unsigned char *sha_retval;
156- uint8_t *signature = NULL;
157- DSA_SIG *dsa_sig = NULL;
158-
159- /* RSA needed variables */
160- RSA *rsa = NULL;
161- unsigned char *e_bin = NULL, *n_bin = NULL, *n_b64 = NULL;
162- char *e_hex = NULL;
163-
164- /* DSA needed variables */
165- DSA *dsa = NULL;
166- unsigned char *p_bin = NULL, *q_bin = NULL, *g_bin = NULL, *y_bin = NULL;
167- unsigned char *p_b64 = NULL, *q_b64 = NULL, *g_b64 = NULL, *y_b64 = NULL;
168-
169- HIP_IFEL(!(cert = calloc(1, sizeof(struct hip_cert_spki_info))),
170- -1, "calloc for cert failed\n");
171- HIP_IFEL(!(p_cert = hip_get_param(msg, HIP_PARAM_CERT_SPKI_INFO)),
172- -1, "No cert_info struct found\n");
173- memcpy(cert, p_cert, sizeof(struct hip_cert_spki_info));
174-
175- HIP_DEBUG_HIT("Getting keys for HIT", &cert->issuer_hit);
176-
177- HIP_IFEL(hip_get_host_id_and_priv_key(&cert->issuer_hit,
178- HIP_ANY_ALGO,
179- &host_id,
180- (void **) &rsa),
181- -1, "Private key not found\n");
182-
183- algo = host_id->rdata.algorithm;
184- if (algo == HIP_HI_DSA) {
185- dsa = (DSA *) rsa;
186- }
187-
188- // Note: EVP_EncodeBlock(unsigned char *t, const unsigned char *f, int dlen) (vintage SSLeay
189- // code) is used to generate the different BASE64 representations. It requires an area of
190- // ((dlen + 2) / 3 * 4 + 1) bytes - so, obviously larger than the size of the input - to be
191- // available for its output (at location "t") - you have been warned.
192- digest_b64 = calloc(1, (SHA_DIGEST_LENGTH + 2) / 3 * 4 + 1);
193- HIP_IFEL(!digest_b64, -1, "calloc for digest_b64 failed\n");
194-
195- /* build sha1 digest that will be signed */
196- HIP_IFEL(!(sha_retval = SHA1((unsigned char *) cert->cert, strlen(cert->cert), sha_digest)),
197- -1, "SHA1 error when creating digest.\n");
198-
199- switch (algo) {
200- case HIP_HI_RSA:
201- sig_len = RSA_size(rsa);
202-
203- signature = calloc(1, sig_len);
204- HIP_IFEL(!signature, -1, "calloc for signature failed\n");
205-
206- signature_b64 = calloc(1, (sig_len + 2) / 3 * 4 + 1);
207- HIP_IFEL(!signature_b64, -1, "calloc for signature_b64 failed\n");
208-
209- n_bin = calloc(1, BN_num_bytes(rsa->n));
210- HIP_IFEL(!n_bin, -1, "calloc for n_bin failed\n");
211-
212- n_b64 = calloc(1, (BN_num_bytes(rsa->n) + 2) / 3 * 4 + 1);
213- HIP_IFEL(!n_b64, -1, "calloc for n_b64 failed\n");
214-
215- e_bin = calloc(1, BN_num_bytes(rsa->e));
216- HIP_IFEL(!e_bin, -1, "calloc for e_bin failed\n");
217-
218- /* RSA sign the digest */
219- err = RSA_sign(NID_sha1, sha_digest, SHA_DIGEST_LENGTH, signature,
220- (unsigned int *) &sig_len, rsa);
221- HIP_IFEL((err = err == 0 ? -1 : 0), -1, "RSA_sign error\n");
222- break;
223- case HIP_HI_ECDSA:
224- HIP_DEBUG("CALL TO UNIMPLEMENTED ECDSA CASE\n");
225- HIP_OUT_ERR(-1, "Unknown algorithm\n");
226- break;
227- case HIP_HI_DSA:
228- p_bin = malloc(BN_num_bytes(dsa->p) + 1);
229- HIP_IFEL(!p_bin, -1, "Malloc for p_bin failed\n");
230-
231- q_bin = malloc(BN_num_bytes(dsa->q) + 1);
232- HIP_IFEL(!q_bin, -1, "Malloc for q_bin failed\n");
233-
234- g_bin = malloc(BN_num_bytes(dsa->g) + 1);
235- HIP_IFEL(!g_bin, -1, "Malloc for g_bin failed\n");
236-
237- y_bin = malloc(BN_num_bytes(dsa->pub_key) + 1);
238- HIP_IFEL(!y_bin, -1, "Malloc for y_bin failed\n");
239-
240- p_b64 = malloc(BN_num_bytes(dsa->p) + 20);
241- HIP_IFEL(!p_b64, -1, "Malloc for p_b64 failed\n");
242-
243- q_b64 = malloc(BN_num_bytes(dsa->q) + 20);
244- HIP_IFEL(!q_b64, -1, "Malloc for q_b64 failed\n");
245-
246- g_b64 = malloc(BN_num_bytes(dsa->g) + 20);
247- HIP_IFEL(!g_b64, -1, "Malloc for g_b64 failed\n");
248-
249- y_b64 = malloc(BN_num_bytes(dsa->pub_key) + 20);
250- HIP_IFEL(!y_b64, -1, "Malloc for y_b64 failed\n");
251-
252-#define HIP_DSA_SIG_SIZE 41 /* T(1) + R(20) + S(20) from RFC 2536 */
253- signature = calloc(1, HIP_DSA_SIG_SIZE);
254-
255- t = BN_num_bytes(dsa->p);
256- t = (t - 64) / 8;
257- HIP_IFEL(t > 8, 1, "Illegal DSA key\n");
258-
259- signature[0] = t;
260- dsa_sig = DSA_do_sign(sha_digest, SHA_DIGEST_LENGTH, dsa);
261- bn2bin_safe(dsa_sig->r, &signature[1], DSA_PRIV);
262- bn2bin_safe(dsa_sig->s, &signature[1 + DSA_PRIV], DSA_PRIV);
263- sig_len = SHA_DIGEST_LENGTH + DSA_PRIV * 2;
264- break;
265- default:
266- HIP_OUT_ERR(-1, "Unknown algorithm for signing\n");
267- }
268-
269- HIP_IFEL(!EVP_EncodeBlock(digest_b64, sha_digest, SHA_DIGEST_LENGTH),
270- -1, "Failed to encode digest_b64\n");
271- HIP_IFEL(!EVP_EncodeBlock(signature_b64, signature, sig_len),
272- -1, "Failed to encode signature_b64\n");
273-
274- /* create (signature (hash sha1 |digest|)|signature|) */
275- sprintf(cert->signature, "(signature (hash sha1 |%s|)|%s|)",
276- digest_b64, signature_b64);
277-
278- /* Create the public key sequence */
279- switch (algo) {
280- case HIP_HI_RSA:
281- /*
282- * RSA public-key
283- * draft-paajarvi-xml-spki-cert-00 section 3.1.1
284- *
285- * <!ELEMENT rsa-pubkey (rsa-e,rsa-n)>
286- * <!ELEMENT rsa-e (#PCDATA)>
287- * <!ELEMENT rsa-n (#PCDATA)>
288- */
289- HIP_IFEL(!BN_bn2bin(rsa->n, n_bin),
290- -1,
291- "Error in converting public exponent from BN to bin\n");
292-
293- HIP_IFEL(!EVP_EncodeBlock(n_b64, n_bin, BN_num_bytes(rsa->n)),
294- -1,
295- "Failed to encode n_b64\n");
296-
297- HIP_IFEL(!BN_bn2bin(rsa->e, e_bin),
298- -1,
299- "Error in converting public exponent from BN to bin\n");
300-
301- e_hex = BN_bn2hex(rsa->e);
302-
303- sprintf(cert->public_key, "(public_key (rsa-pkcs1-sha1 (e #%s#)(n |%s|)))",
304- e_hex,
305- n_b64);
306- break;
307- case HIP_HI_ECDSA:
308- HIP_DEBUG("CALL TO UNIMPLEMENTED ECDSA CASE\n");
309- HIP_OUT_ERR(-1, "Unknown algorithm for signing\n");
310- break;
311- case HIP_HI_DSA:
312- /*
313- * DSA public-key
314- * draft-paajarvi-xml-spki-cert-00 section 3.1.2
315- *
316- * <!ELEMENT dsa-pubkey (dsa-p,dsa-q,dsa-g,dsa-y)>
317- * <!ELEMENT dsa-p (#PCDATA)>
318- * <!ELEMENT dsa-q (#PCDATA)>
319- * <!ELEMENT dsa-g (#PCDATA)>
320- * <!ELEMENT dsa-y (#PCDATA)>
321- */
322- HIP_IFEL(!BN_bn2bin(dsa->p, p_bin), -1,
323- "Error in converting public exponent from BN to bin\n");
324- HIP_IFEL(!EVP_EncodeBlock(p_b64, p_bin, BN_num_bytes(dsa->p)),
325- -1, "Failed to encode p_b64\n");
326-
327- HIP_IFEL(!BN_bn2bin(dsa->q, q_bin), -1,
328- "Error in converting public exponent from BN to bin\n");
329- HIP_IFEL(!EVP_EncodeBlock(q_b64, q_bin, BN_num_bytes(dsa->q)),
330- -1, "Failed to encode q_64");
331-
332- HIP_IFEL(!(BN_bn2bin(dsa->g, g_bin)), -1,
333- "Error in converting public exponent from BN to bin\n");
334- HIP_IFEL(!EVP_EncodeBlock(g_b64, g_bin, BN_num_bytes(dsa->g)),
335- -1, "Failed to encode g_b64\n");
336-
337- HIP_IFEL(!BN_bn2bin(dsa->pub_key, y_bin), -1,
338- "Error in converting public exponent from BN to bin\n");
339- HIP_IFEL(!EVP_EncodeBlock(y_b64, y_bin, BN_num_bytes(dsa->pub_key)),
340- -1, "Failed to encode y_b64\n");
341-
342- sprintf(cert->public_key, "(public_key (dsa-pkcs1-sha1 (p |%s|)(q |%s|)"
343- "(g |%s|)(y |%s|)))",
344- p_b64, q_b64, g_b64, y_b64);
345- break;
346- default:
347- HIP_OUT_ERR(-1, "Unknown algorithm for public-key element\n");
348- }
349-
350- /* Put the results into the msg back */
351- hip_msg_init(msg);
352-
353- HIP_IFEL(hip_build_user_hdr(msg, HIP_MSG_CERT_SPKI_SIGN, 0), -1,
354- "Failed to build user header\n");
355- HIP_IFEL(hip_build_param_cert_spki_info(msg, cert), -1,
356- "Failed to build cert_info\n");
357-
358-out_err:
359-
360- /* free malloced memory */
361- free(digest_b64);
362- free(signature_b64);
363- free(signature);
364- free(host_id);
365-
366- /* RSA pubkey */
367- free(e_bin);
368- free(n_bin);
369- /* encoded */
370- OPENSSL_free(e_hex);
371- free(n_b64);
372-
373- /* DSA pubkey */
374- free(p_bin);
375- free(q_bin);
376- free(g_bin);
377- free(y_bin);
378- /* encoded */
379- free(p_b64);
380- free(q_b64);
381- free(g_b64);
382- free(y_b64);
383-
384- DSA_SIG_free(dsa_sig);
385-
386- free(cert);
387-
388- return err;
389-}
390-
391-/**
392- * Function that verifies the signature in the given SPKI cert sent by
393- * the "client"
394- *
395- * @param msg points to the msg gotten from "client" that contains a
396- * spki cert in CERT parameter
397- *
398- * @return 0 if signature matches, -1 if error or signature did NOT match
399- */
400-int hip_cert_spki_verify(struct hip_common *msg)
401-{
402- int err = 0, start = 0, stop = 0, evpret = 0, keylen = 0, algo = 0;
403- char buf[200];
404-
405- unsigned char sha_digest[21];
406- unsigned char *sha_retval;
407- unsigned char *signature_hash = NULL;
408- unsigned char *signature_hash_b64 = NULL;
409- unsigned char *signature_b64 = NULL;
410-
411- const struct hip_cert_spki_info *p_cert;
412- struct hip_cert_spki_info *cert = NULL;
413- unsigned char *signature = NULL;
414-
415- /** RSA */
416- RSA *rsa = NULL;
417- unsigned long e_code;
418- char *e_hex = NULL;
419- unsigned char *modulus_b64 = NULL;
420- unsigned char *modulus = NULL;
421-
422- /** DSA */
423- DSA *dsa = NULL;
424- unsigned char *p_bin = NULL, *q_bin = NULL, *g_bin = NULL, *y_bin = NULL;
425- unsigned char *p_b64 = NULL, *q_b64 = NULL, *g_b64 = NULL, *y_b64 = NULL;
426- DSA_SIG *dsa_sig = NULL;
427-
428- /* rules for regular expressions */
429-
430- /*
431- * Rule to get the info if we are using DSA
432- */
433- char dsa_rule[] = "[d][s][a][-][p][k][c][s][1][-][s][h][a][1]";
434-
435- /*
436- * Rule to get the info if we are using RSA
437- */
438- char rsa_rule[] = "[r][s][a][-][p][k][c][s][1][-][s][h][a][1]";
439-
440- /*
441- * Rule to get DSA p
442- * Look for pattern "(p |" and stop when first "|"
443- * anything in base 64 is accepted inbetween
444- */
445- char p_rule[] = "[(][p][ ][|][[A-Za-z0-9+/()#=-]*[|]";
446-
447- /*
448- * Rule to get DSA q
449- * Look for pattern "(q |" and stop when first "|"
450- * anything in base 64 is accepted inbetween
451- */
452- char q_rule[] = "[(][q][ ][|][[A-Za-z0-9+/()#=-]*[|]";
453-
454- /*
455- * Rule to get DSA g
456- * Look for pattern "(g |" and stop when first "|"
457- * anything in base 64 is accepted inbetween
458- */
459- char g_rule[] = "[(][g][ ][|][[A-Za-z0-9+/()#=-]*[|]";
460-
461- /*
462- * Rule to get DSA y / pub_key
463- * Look for pattern "(y |" and stop when first "|"
464- * anything in base 64 is accepted inbetween
465- */
466- char y_rule[] = "[(][y][ ][|][[A-Za-z0-9+/()#=-]*[|]";
467-
468- /*
469- * rule to get the public exponent RSA
470- * Look for the part that says # and after that some hex blob and #
471- */
472- char e_rule[] = "[#][0-9A-Fa-f]*[#]";
473-
474- /*
475- * rule to get the public modulus RSA
476- * Look for the part that starts with '|' and after that anything
477- * that is in base 64 char set and then '|' again
478- */
479- char n_rule[] = "[|][A-Za-z0-9+/()#=-]*[|]";
480-
481- /*
482- * rule to get the signature hash
483- * Look for the similar than the n_rule
484- */
485- char h_rule[] = "[|][A-Za-z0-9+/()#=-]*[|]";
486-
487- /*
488- * rule to get the signature
489- * Look for part that starts ")|" and base 64 blob after it
490- * and stops to '|' char remember to add and subtract 2 from
491- * the indexes below
492- */
493- char s_rule[] = "[)][|][A-Za-z0-9+/()#=-]*[|]";
494-
495- cert = calloc(1, sizeof(struct hip_cert_spki_info));
496- HIP_IFEL(!cert, -1, "calloc for cert failed\n");
497-
498- HIP_IFEL(!(p_cert = hip_get_param(msg, HIP_PARAM_CERT_SPKI_INFO)),
499- -1, "No cert_info struct found\n");
500- memcpy(cert, p_cert, sizeof(struct hip_cert_spki_info));
501-
502- /* check the algo DSA or RSA */
503- HIP_DEBUG("Verifying\nRunning regexps to identify algo\n");
504- start = stop = 0;
505- algo = hip_cert_regex(dsa_rule, cert->public_key, &start, &stop);
506- if (algo != -1) {
507- HIP_DEBUG("Public-key is DSA\n");
508- algo = HIP_HI_DSA;
509- goto algo_check_done;
510- }
511- start = stop = 0;
512- algo = hip_cert_regex(rsa_rule, cert->public_key, &start, &stop);
513- if (algo != -1) {
514- HIP_DEBUG("Public-key is RSA\n");
515- algo = HIP_HI_RSA;
516- goto algo_check_done;
517- }
518-
519-algo_check_done:
520- switch (algo) {
521- case HIP_HI_RSA:
522- /* malloc space for new rsa */
523- rsa = RSA_new();
524- HIP_IFEL(!rsa, -1, "Failed to malloc RSA\n");
525-
526- /* extract the public-key from cert to rsa */
527-
528- /* public exponent first */
529- start = stop = 0;
530- HIP_IFEL(hip_cert_regex(e_rule, cert->public_key, &start, &stop), -1,
531- "Failed to run hip_cert_regex (exponent)\n");
532- e_hex = malloc(stop - start);
533- HIP_IFEL(!e_hex, -1, "Malloc for e_hex failed\n");
534- snprintf(e_hex, stop - start - 1, "%s", &cert->public_key[start + 1]);
535-
536- /* public modulus */
537- start = stop = 0;
538- HIP_IFEL(hip_cert_regex(n_rule, cert->public_key, &start, &stop), -1,
539- "Failed to run hip_cert_regex (modulus)\n");
540- modulus_b64 = calloc(1, stop - start + 1);
541- HIP_IFEL(!modulus_b64, -1, "calloc for modulus_b64 failed\n");
542- modulus = calloc(1, stop - start + 1);
543- HIP_IFEL(!modulus, -1, "calloc for modulus failed\n");
544- snprintf((char *) modulus_b64, stop - start - 1, "%s",
545- &cert->public_key[start + 1]);
546-
547- /* put the stuff into the RSA struct */
548- BN_hex2bn(&rsa->e, e_hex);
549- evpret = EVP_DecodeBlock(modulus, modulus_b64,
550- strlen((char *) modulus_b64));
551-
552- /* EVP returns a multiple of 3 octets, subtract any extra */
553- keylen = evpret;
554- if (keylen % 4 != 0) {
555- --keylen;
556- keylen = keylen - keylen % 2;
557- }
558- signature = malloc(keylen);
559- HIP_IFEL(!signature, -1, "Malloc for signature failed.\n");
560- rsa->n = BN_bin2bn(modulus, keylen, 0);
561- break;
562- case HIP_HI_DSA:
563- /* malloc space for new dsa */
564- dsa = DSA_new();
565- HIP_IFEL(!dsa, -1, "Failed to malloc DSA\n");
566-
567- /* Extract public key from the cert */
568-
569- /* dsa->p */
570- start = stop = 0;
571- HIP_IFEL(hip_cert_regex(p_rule, cert->public_key, &start, &stop), -1,
572- "Failed to run hip_cert_regex dsa->p\n");
573- p_b64 = calloc(1, stop - start + 1);
574- HIP_IFEL(!p_b64, -1, "calloc for p_b64 failed\n");
575- p_bin = calloc(1, stop - start + 1);
576- HIP_IFEL(!p_bin, -1, "calloc for p_bin failed\n");
577- snprintf((char *) p_b64, stop - start - 1, "%s",
578- &cert->public_key[start + 1]);
579- evpret = EVP_DecodeBlock(p_bin, p_b64, strlen((char *) p_b64));
580-
581- /* dsa->q */
582- start = stop = 0;
583- HIP_IFEL(hip_cert_regex(q_rule, cert->public_key, &start, &stop), -1,
584- "Failed to run hip_cert_regex dsa->q\n");
585- q_b64 = calloc(1, stop - start + 1);
586- HIP_IFEL(!q_b64, -1, "calloc for q_b64 failed\n");
587- q_bin = calloc(1, stop - start + 1);
588- HIP_IFEL(!q_bin, -1, "calloc for q_bin failed\n");
589- snprintf((char *) q_b64, stop - start - 1, "%s",
590- &cert->public_key[start + 1]);
591- evpret = EVP_DecodeBlock(q_bin, q_b64, strlen((char *) q_b64));
592-
593- /* dsa->g */
594- start = stop = 0;
595- HIP_IFEL(hip_cert_regex(g_rule, cert->public_key, &start, &stop), -1,
596- "Failed to run hip_cert_regex dsa->g\n");
597- g_b64 = calloc(1, stop - start + 1);
598- HIP_IFEL(!g_b64, -1, "calloc for g_b64 failed\n");
599- g_bin = calloc(1, stop - start + 1);
600- HIP_IFEL(!g_bin, -1, "calloc for g_bin failed\n");
601- snprintf((char *) g_b64, stop - start - 1, "%s",
602- &cert->public_key[start + 1]);
603- evpret = EVP_DecodeBlock(g_bin, g_b64, strlen((char *) g_b64));
604-
605- /* dsa->y */
606- start = stop = 0;
607- HIP_IFEL(hip_cert_regex(y_rule, cert->public_key, &start, &stop), -1,
608- "Failed to run hip_cert_regex dsa->y\n");
609- y_b64 = calloc(1, stop - start + 1);
610- HIP_IFEL(!y_b64, -1, "calloc for y_b64 failed\n");
611- y_bin = calloc(1, stop - start + 1);
612- HIP_IFEL(!y_bin, -1, "calloc for y_bin failed\n");
613- snprintf((char *) y_b64, stop - start - 1, "%s",
614- &cert->public_key[start + 1]);
615- evpret = EVP_DecodeBlock(y_bin, y_b64, strlen((char *) y_b64));
616- break;
617- case HIP_HI_ECDSA:
618- HIP_DEBUG("CALL TO UNIMPLEMENTED ECDSA CASE\n");
619- HIP_OUT_ERR(-1, "Unknown algorithm\n");
620- break;
621- default:
622- HIP_OUT_ERR(-1, "Unknown algorithm\n");
623- }
624-
625- /* build sha1 digest that will be signed */
626- HIP_IFEL(!(sha_retval = SHA1((unsigned char *) cert->cert,
627- strlen(cert->cert), sha_digest)),
628- -1, "SHA1 error when creating digest.\n");
629-
630- /* Get the signature hash and compare it to the sha_digest we just made */
631- start = stop = 0;
632- HIP_IFEL(hip_cert_regex(h_rule, cert->signature, &start, &stop), -1,
633- "Failed to run hip_cert_regex (signature hash)\n");
634- signature_hash_b64 = calloc(1, stop - start + 1);
635- HIP_IFEL(!signature_hash_b64, -1, "Failed to calloc signature_hash_b64\n");
636- signature_hash = malloc(stop - start + 1);
637- HIP_IFEL(!signature_hash, -1, "Failed to malloc signature_hash\n");
638- snprintf((char *) signature_hash_b64, stop - start - 1, "%s",
639- &cert->signature[start + 1]);
640- evpret = EVP_DecodeBlock(signature_hash, signature_hash_b64,
641- strlen((char *) signature_hash_b64));
642- HIP_IFEL(memcmp(sha_digest, signature_hash, 20), -1,
643- "Signature hash did not match of the one made from the"
644- "cert sequence in the certificate\n");
645-
646- /* memset signature and put it into its place */
647- start = stop = 0;
648- HIP_IFEL(hip_cert_regex(s_rule, cert->signature, &start, &stop), -1,
649- "Failed to run hip_cert_regex (signature)\n");
650- signature_b64 = calloc(1, stop - start + 1);
651- HIP_IFEL(!signature_b64, -1, "Failed to calloc signature_b64\n");
652- snprintf((char *) signature_b64, stop - start - 2, "%s",
653- &cert->signature[start + 2]);
654- if (algo == HIP_HI_DSA) {
655- signature = malloc(stop - start + 1);
656- HIP_IFEL(!signature, -1, "Failed to malloc signature (dsa)\n");
657- }
658- evpret = EVP_DecodeBlock(signature, signature_b64,
659- strlen((char *) signature_b64));
660-
661- switch (algo) {
662- case HIP_HI_RSA:
663- /* do the verification */
664- err = RSA_verify(NID_sha1, sha_digest, SHA_DIGEST_LENGTH,
665- signature, RSA_size(rsa), rsa);
666- e_code = ERR_get_error();
667- ERR_load_crypto_strings();
668- ERR_error_string(e_code, buf);
669-
670- /* RSA_verify returns 1 if success. */
671- cert->success = err == 1 ? 0 : -1;
672- HIP_IFEL((err = err == 1 ? 0 : -1), -1, "RSA_verify error\n");
673- break;
674- case HIP_HI_DSA:
675- /* build the signature structure */
676- dsa_sig = DSA_SIG_new();
677- HIP_IFEL(!dsa_sig, 1, "Failed to allocate DSA_SIG\n");
678- dsa_sig->r = BN_bin2bn(&signature[1], DSA_PRIV, NULL);
679- dsa_sig->s = BN_bin2bn(&signature[1 + DSA_PRIV], DSA_PRIV, NULL);
680-
681- /* verify the DSA signature */
682- err = DSA_do_verify(sha_digest, SHA_DIGEST_LENGTH,
683- dsa_sig, dsa) == 0 ? 1 : 0;
684-
685- /* DSA_do_verify returns 1 if success. */
686- cert->success = err == 1 ? 0 : -1;
687- HIP_IFEL((err = err == 1 ? 0 : -1), -1, "DSA_do_verify error\n");
688- break;
689- case HIP_HI_ECDSA:
690- HIP_DEBUG("CALL TO UNIMPLEMENTED ECDSA CASE\n");
691- HIP_OUT_ERR(-1, "Unknown algorithm for signing\n");
692- break;
693- default:
694- HIP_OUT_ERR(-1, "Unknown algorithm\n");
695- }
696-
697- hip_msg_init(msg);
698-
699- HIP_IFEL(hip_build_user_hdr(msg, HIP_MSG_CERT_SPKI_SIGN, 0), -1,
700- "Failed to build user header\n");
701- HIP_IFEL(hip_build_param_cert_spki_info(msg, cert), -1,
702- "Failed to build cert_info\n");
703-
704-out_err:
705- free(signature_hash_b64);
706- free(signature_hash);
707- free(modulus_b64);
708- free(modulus);
709- free(cert);
710- free(signature);
711- free(e_hex);
712- RSA_free(rsa);
713- DSA_free(dsa);
714- DSA_SIG_free(dsa_sig);
715-
716- return err;
717-}
718-
719-/****************************************************************************
720- *
721- * X.509v3
722- *
723- ***************************************************************************/
724-
725-/**
726- * Function that creates the certificate and sends it to back to the client.
727- *
728- * @param msg is a pointer to the msg containing a x509v3 cert in cert parameter
729- *
730- * @return 0 on success negative otherwise.
731- */
732-int hip_cert_x509v3_handle_request_to_sign(struct hip_common *msg)
733-{
734- int err = 0, i = 0, nid = 0, ret = 0, secs = 0, algo = 0;
735- CONF *conf;
736- CONF_VALUE *item;
737- STACK_OF(CONF_VALUE) *sec_general = NULL;
738- STACK_OF(CONF_VALUE) *sec_name = NULL;
739- STACK_OF(CONF_VALUE) *sec_ext = NULL;
740-
741- X509_REQ *req = NULL;
742- X509_NAME *issuer = NULL;
743- X509_NAME *subj = NULL;
744- X509_EXTENSION *ext = NULL;
745- STACK_OF(X509_EXTENSION) *extlist = NULL;
746- X509_NAME_ENTRY *ent;
747- EVP_PKEY *pkey;
748- /** XX TODO THIS should come from a configuration file
749- * monotonically increasing counter */
750- long serial = 0;
751- const EVP_MD *digest = NULL;
752- X509 *cert;
753- X509V3_CTX ctx;
754- const struct hip_cert_x509_req *subject;
755- char subject_hit[41];
756- char issuer_hit[41];
757- char ialtname[45];
758- char saltname[45];
759- struct in6_addr *issuer_hit_n;
760- struct hip_host_id *host_id;
761- RSA *rsa = NULL;
762- DSA *dsa = NULL;
763- unsigned char *der_cert = NULL;
764- int der_cert_len = 0;
765- char arg1[21];
766- char arg2[21];
767-
768- HIP_IFEL(!(issuer_hit_n = malloc(sizeof(struct in6_addr))), -1,
769- "Malloc for subject failed\n");
770- HIP_IFEL(!(pkey = malloc(sizeof(EVP_PKEY))), -1,
771- "Malloc for pkey failed\n");
772-
773- OpenSSL_add_all_algorithms();
774- ERR_load_crypto_strings();
775-
776- HIP_DEBUG("Reading configuration file (%s)\n", HIP_CERT_CONF_PATH);
777- conf = hip_open_conf(HIP_CERT_CONF_PATH);
778- sec_general = hip_read_conf_section("hip_x509v3", conf);
779- sec_name = hip_read_conf_section("hip_x509v3_name", conf);
780- sec_ext = hip_read_conf_section("hip_x509v3_extensions", conf);
781- NCONF_free(conf);
782-
783- /* Get the general information */
784- HIP_IFEL(sec_general == NULL, -1,
785- "Failed to load general certificate information\n");
786- HIP_IFEL(!(req = X509_REQ_new()), -1, "Failed to create X509_REQ object");
787-
788- HIP_IFEL(sec_name == NULL, -1,
789- "Failed to load issuer naming information for the certificate\n");
790-
791- /* Issuer naming */
792- if (sec_general != NULL) {
793- /* Loop through the conf stack for general information */
794- extlist = sk_X509_EXTENSION_new_null();
795- for (i = 0; i < sk_CONF_VALUE_num(sec_general); i++) {
796- item = sk_CONF_VALUE_value(sec_general, i);
797- if (!strcmp(item->name, "issuerhit")) {
798- strcpy(issuer_hit, item->value);
799- ret = inet_pton(AF_INET6, item->value, issuer_hit_n);
800- HIP_IFEL(ret < 0 && errno == EAFNOSUPPORT, -1,
801- "Failed to convert issuer HIT to hip_hit_t\n");
802- HIP_DEBUG_HIT("Issuer HIT", issuer_hit_n);
803- HIP_IFEL(!inet_ntop(AF_INET6, issuer_hit_n,
804- issuer_hit, sizeof(issuer_hit)),
805- -1, "Failed to convert subject hit to "
806- "presentation format\n");
807- }
808- if (!strcmp(item->name, "days")) {
809- secs = HIP_CERT_DAY * atoi(item->value);
810- }
811- }
812- }
813- HIP_IFEL(!(issuer = X509_NAME_new()), -1, "Failed to set create issuer name");
814- nid = OBJ_txt2nid("commonName");
815- HIP_IFEL(nid == NID_undef, -1, "NID text not defined\n");
816- HIP_IFEL(!(ent = X509_NAME_ENTRY_create_by_NID(NULL, nid, MBSTRING_ASC,
817- (unsigned char *) issuer_hit, -1)), -1,
818- "Failed to create name entry for issuer\n");
819- HIP_IFEL(X509_NAME_add_entry(issuer, ent, -1, 0) != 1, -1,
820- "Failed to add entry to issuer name\n");
821-
822- /* Subject naming */
823- /* Get the subject hit from msg */
824- HIP_IFEL(!(subject = hip_get_param(msg, HIP_PARAM_CERT_X509_REQ)),
825- -1, "No cert_info struct found\n");
826- HIP_IFEL(!inet_ntop(AF_INET6, &subject->addr, subject_hit, sizeof(subject_hit)),
827- -1, "Failed to convert subject hit to presentation format\n");
828- HIP_IFEL(!(subj = X509_NAME_new()), -1, "Failed to set create subject name");
829- nid = OBJ_txt2nid("commonName");
830- HIP_IFEL(nid == NID_undef, -1, "NID text not defined\n");
831- HIP_IFEL(!(ent = X509_NAME_ENTRY_create_by_NID(NULL, nid, MBSTRING_ASC,
832- (unsigned char *) subject_hit, -1)), -1,
833- "Failed to create name entry for subject\n");
834- HIP_IFEL(X509_NAME_add_entry(subj, ent, -1, 0) != 1, -1,
835- "Failed to add entry to subject name\n");
836- HIP_IFEL(X509_REQ_set_subject_name(req, subj) != 1, -1,
837- "Failed to add subject name to certificate request\n");
838-
839- /* XX TODO add a check to skip subjectAltName and issuerAltName because they are
840- * already in use by with IP:<hit> stuff */
841- if (sec_ext != NULL) {
842- /* Loop through the conf stack and add extensions to ext stack */
843- extlist = sk_X509_EXTENSION_new_null();
844- for (i = 0; i < sk_CONF_VALUE_num(sec_ext); i++) {
845- item = sk_CONF_VALUE_value(sec_ext, i);
846- HIP_IFEL(!(ext = X509V3_EXT_conf(NULL, &ctx,
847- item->name, item->value)), -1,
848- "Failed to create extension\n");
849- sk_X509_EXTENSION_push(extlist, ext);
850- }
851- HIP_IFEL(!X509_REQ_add_extensions(req, extlist), -1,
852- "Failed to add extensions to the request\n");
853- }
854-
855- /** NOW WE ARE READY TO CREATE A CERTIFICATE FROM THE REQUEST */
856- HIP_DEBUG("Starting the certificate creation\n");
857-
858- HIP_IFEL(!(cert = X509_new()), -1,
859- "Failed to create X509 object\n");
860-
861- HIP_IFEL(X509_set_version(cert, 2L) != 1, -1,
862- "Failed to set certificate version\n");
863- /** XX TODO serial should be stored after increasing it */
864- ASN1_INTEGER_set(X509_get_serialNumber(cert), serial++);
865-
866- HIP_IFEL(X509_set_subject_name(cert, subj) != 1, -1,
867- "Failed to set subject name of certificate\n");
868- HIP_IFEL(X509_set_issuer_name(cert, issuer) != 1, -1,
869- "Failed to set issuer name of certificate\n");
870- HIP_IFEL(!X509_gmtime_adj(X509_get_notBefore(cert), 0), -1,
871- "Error setting beginning time of the certificate");
872- HIP_IFEL(!X509_gmtime_adj(X509_get_notAfter(cert), secs), -1,
873- "Error setting ending time of the certificate");
874-
875- HIP_DEBUG("Getting the key\n");
876-
877- HIP_IFEL(hip_get_host_id_and_priv_key(issuer_hit_n,
878- HIP_ANY_ALGO,
879- &host_id,
880- (void *) &rsa),
881- -1, "Private key not found\n");
882-
883- algo = host_id->rdata.algorithm;
884- if (algo == HIP_HI_DSA) {
885- dsa = (DSA *) rsa;
886- }
887-
888- switch (algo) {
889- case HIP_HI_RSA:
890- HIP_IFEL(!EVP_PKEY_assign_RSA(pkey, rsa), -1,
891- "Failed to convert RSA to EVP_PKEY\n");
892- HIP_IFEL(X509_set_pubkey(cert, pkey) != 1, -1,
893- "Failed to set public key of the certificate\n");
894- break;
895- case HIP_HI_DSA:
896- HIP_IFEL(!EVP_PKEY_assign_DSA(pkey, dsa), -1,
897- "Failed to convert DSA to EVP_PKEY\n");
898- HIP_IFEL(X509_set_pubkey(cert, pkey) != 1, -1,
899- "Failed to set public key of the certificate\n");
900- break;
901- case HIP_HI_ECDSA:
902- HIP_DEBUG("CALL TO UNIMPLEMENTED ECDSA CASE\n");
903- HIP_OUT_ERR(-1, "Unknown algorithm for signing\n");
904- break;
905- default:
906- HIP_OUT_ERR(-1, "Unknown algorithm\n");
907- }
908-
909- if (sec_ext != NULL) {
910- for (i = 0; i < sk_CONF_VALUE_num(sec_ext); i++) {
911- item = sk_CONF_VALUE_value(sec_ext, i);
912- /*
913- * Skip issuerAltName and subjectAltName because
914- * HITs use them already. Skip also basicConstraint =
915- * CA:true and subjectKeyIdentifier because they are
916- * added automatically in the code below
917- */
918- if (!strcmp(item->name, "issuerAltname")) {
919- continue;
920- }
921- if (!strcmp(item->name, "subjectAltname")) {
922- continue;
923- }
924- if (0 == memcmp(subject_hit, issuer_hit, sizeof(issuer_hit))) {
925- if (!strcmp(item->name, "basicConstraints") &&
926- !strcmp(item->value, "CA:true")) {
927- continue;
928- }
929- if (!strcmp(item->name, "subjectKeyIdentifier")) {
930- continue;
931- }
932- }
933- HIP_IFEL(!(ext = X509V3_EXT_conf(NULL, &ctx,
934- item->name, item->value)), -1,
935- "Failed to create extension\n");
936- HIP_IFEL(!X509_add_ext(cert, ext, -1), -1,
937- "Failed to add extensions to the cert\n");
938- }
939- }
940-
941- if (0 == memcmp(subject_hit, issuer_hit, sizeof(issuer_hit))) {
942- /* Subjects and issuers hit match so
943- * we are writing a CA cert and in CA self-signed
944- * certificate you have to have subject key identifier
945- * present, when adding subjectKeyIdentifier give string
946- * hash to the X509_EXT_conf it knows what to do with it */
947-
948- /* X509V3_EXT_conf() doesn't accept const char *, so we
949- * write the arguments to a buffer first */
950- sprintf(arg1, "basicConstraints");
951- sprintf(arg2, "CA:true");
952- HIP_IFEL(!(ext = X509V3_EXT_conf(NULL, &ctx,
953- arg1, arg2)), -1,
954- "Failed to create extension\n");
955- HIP_IFEL(!X509_add_ext(cert, ext, -1), -1,
956- "Failed to add extensions to the cert\n");
957-
958- sprintf(arg1, "subjectKeyIdentifier");
959- sprintf(arg2, "hash");
960- HIP_IFEL(!(ext = X509V3_EXT_conf(NULL, &ctx,
961- arg1, arg2)), -1,
962- "Failed to create extension\n");
963- HIP_IFEL(!X509_add_ext(cert, ext, -1), -1,
964- "Failed to add extensions to the cert\n");
965- }
966-
967- /* add subjectAltName = IP:<HIT> */
968- sprintf(arg1, "issuerAltName");
969- sprintf(ialtname, "IP:%s", issuer_hit);
970- HIP_IFEL(!(ext = X509V3_EXT_conf(NULL, &ctx,
971- arg1, ialtname)), -1,
972- "Failed to create extension\n");
973- HIP_IFEL(!X509_add_ext(cert, ext, -1), -1,
974- "Failed to add extensions to the cert\n");
975- /* add subjectAltName = IP:<HIT> */
976- sprintf(arg1, "subjectAltName");
977- sprintf(saltname, "IP:%s", subject_hit);
978- HIP_IFEL(!(ext = X509V3_EXT_conf(NULL, &ctx,
979- arg1, saltname)), -1,
980- "Failed to create extension\n");
981- HIP_IFEL(!X509_add_ext(cert, ext, -1), -1,
982- "Failed to add extensions to the cert\n");
983-
984- switch (algo) {
985- case HIP_HI_RSA:
986- digest = EVP_sha1();
987- break;
988- case HIP_HI_DSA:
989- digest = EVP_dss1();
990- break;
991- case HIP_HI_ECDSA:
992- HIP_DEBUG("CALL TO UNIMPLEMENTED ECDSA CASE\n");
993- HIP_OUT_ERR(-1, "Unknown algorithm for signing\n");
994- break;
995- default:
996- HIP_OUT_ERR(-1, "Unknown algorithm\n");
997- }
998-
999- HIP_IFEL(!X509_sign(cert, pkey, digest), -1,
1000- "Failed to sign x509v3 certificate\n");
1001-
1002- /** DER */
1003- HIP_IFEL((der_cert_len = i2d_X509(cert, &der_cert)) < 0, -1,
1004- "Failed to convert cert to DER\n");
1005- /** end DER */
1006-
1007- hip_msg_init(msg);
1008-
1009- HIP_IFEL(hip_build_user_hdr(msg, HIP_MSG_CERT_X509V3_SIGN, 0), -1,
1010- "Failed to build user header\n");
1011- HIP_IFEL(hip_build_param_cert_x509_resp(msg, (char *) der_cert, der_cert_len), -1,
1012- "Failed to create x509 response parameter\n");
1013-
1014-out_err:
1015- free(host_id);
1016- X509_REQ_free(req);
1017- sk_X509_EXTENSION_pop_free(extlist, X509_EXTENSION_free);
1018- return err;
1019-}
1020-
1021-static int verify_callback(int ok, DBG X509_STORE_CTX *stor)
1022-{
1023- /* This is not called from anywhere else than this file */
1024- if (!ok) {
1025- HIP_DEBUG("Error: %s\n", X509_verify_cert_error_string(stor->error));
1026- }
1027- return ok;
1028-}
1029-
1030-/**
1031- * Function verifies the given certificate and sends it to back to the client.
1032- *
1033- * @param msg is a pointer to the requesting msg that contains a cert parameter with x509v3 cert
1034- *
1035- * @return 0 on success negative otherwise.
1036- */
1037-int hip_cert_x509v3_handle_request_to_verify(struct hip_common *msg)
1038-{
1039- int err = 0;
1040- struct hip_cert_x509_resp verify;
1041- const struct hip_cert_x509_resp *p;
1042- X509 *cert = NULL;
1043- X509_STORE *store = NULL;
1044- X509_STORE_CTX *verify_ctx = NULL;
1045- unsigned char *der_cert = NULL;
1046- const unsigned char *vessel;
1047-
1048- OpenSSL_add_all_algorithms();
1049- ERR_load_crypto_strings();
1050-
1051- HIP_IFEL(!(p = hip_get_param(msg, HIP_PARAM_CERT_X509_REQ)), -1,
1052- "Failed to get cert info from the msg\n");
1053- memcpy(&verify, p, sizeof(struct hip_cert_x509_resp));
1054-
1055- der_cert = (unsigned char *) &p->der;
1056-
1057- vessel = p->der;
1058- HIP_IFEL((cert = d2i_X509(NULL, &vessel, verify.der_len)) == NULL, -1,
1059- "Failed to convert cert from DER to internal format\n");
1060- /*
1061- * HIP_IFEL(!X509_print_fp(stdout, cert), -1,
1062- * "Failed to print x.509v3 in human readable format\n");
1063- */
1064-
1065- HIP_IFEL(!(store = X509_STORE_new()), -1,
1066- "Failed to create X509_STORE_CTX object\n");
1067- X509_STORE_set_verify_cb_func(store, verify_callback);
1068-
1069- /* self signed so te cert itself should verify itself */
1070-
1071- HIP_IFEL(!X509_STORE_add_cert(store, cert), -1,
1072- "Failed to add cert to ctx\n");
1073-
1074- HIP_IFEL(!(verify_ctx = X509_STORE_CTX_new()), -1,
1075- "Failed to create X509_STORE_CTX object\n");
1076-
1077- HIP_IFEL(X509_STORE_CTX_init(verify_ctx, store, cert, NULL) != 1, -1,
1078- "Failed to initialize verification context\n");
1079-
1080- if (X509_verify_cert(verify_ctx) != 1) {
1081- HIP_DEBUG("Error verifying the certificate\n");
1082- err = -1;
1083- } else {
1084- HIP_DEBUG("Certificate verified correctly!\n");
1085- err = 0;
1086- }
1087-
1088- hip_msg_init(msg);
1089- HIP_IFEL(hip_build_user_hdr(msg, HIP_MSG_CERT_X509V3_VERIFY, err), -1,
1090- "Failed to build user header\n");
1091- HIP_IFEL(hip_build_param_cert_x509_resp(msg, (char *) &der_cert, p->der_len), -1,
1092- "Failed to create x509 response parameter\n");
1093-
1094-out_err:
1095- X509_STORE_CTX_cleanup(verify_ctx);
1096- X509_STORE_free(store);
1097- X509_free(cert);
1098- return err;
1099-}
1100
1101=== removed file 'hipd/cert.h'
1102--- hipd/cert.h 2011-11-25 17:56:24 +0000
1103+++ hipd/cert.h 1970-01-01 00:00:00 +0000
1104@@ -1,48 +0,0 @@
1105-/*
1106- * Copyright (c) 2010 Aalto University and RWTH Aachen University.
1107- *
1108- * Permission is hereby granted, free of charge, to any person
1109- * obtaining a copy of this software and associated documentation
1110- * files (the "Software"), to deal in the Software without
1111- * restriction, including without limitation the rights to use,
1112- * copy, modify, merge, publish, distribute, sublicense, and/or sell
1113- * copies of the Software, and to permit persons to whom the
1114- * Software is furnished to do so, subject to the following
1115- * conditions:
1116- *
1117- * The above copyright notice and this permission notice shall be
1118- * included in all copies or substantial portions of the Software.
1119- *
1120- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
1121- * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
1122- * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
1123- * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
1124- * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
1125- * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
1126- * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
1127- * OTHER DEALINGS IN THE SOFTWARE.
1128- */
1129-
1130-/**
1131- * @file
1132- *
1133- * Certificate signing and verification functions.
1134- */
1135-
1136-#ifndef HIPL_HIPD_CERT_H
1137-#define HIPL_HIPD_CERT_H
1138-
1139-#include <openssl/rsa.h>
1140-
1141-#include "lib/core/hashtable.h"
1142-#include "lib/core/protodefs.h"
1143-
1144-/** SPKI */
1145-int hip_cert_spki_sign(struct hip_common *);
1146-int hip_cert_spki_verify(struct hip_common *);
1147-
1148-/** x509v3 */
1149-int hip_cert_x509v3_handle_request_to_sign(struct hip_common *);
1150-int hip_cert_x509v3_handle_request_to_verify(struct hip_common *);
1151-
1152-#endif /* HIPL_HIPD_CERT_H */
1153
1154=== modified file 'hipd/init.c'
1155--- hipd/init.c 2012-01-18 21:21:26 +0000
1156+++ hipd/init.c 2012-02-20 21:55:24 +0000
1157@@ -435,81 +435,6 @@
1158 return err;
1159 }
1160
1161-/* Needed if the configuration file for certs did not exist */
1162-#define HIP_CERT_INIT_DAYS 10
1163-
1164-/**
1165- * Initialize certificates for the local host
1166- *
1167- * @return zero on success or negative on failure
1168- */
1169-static int init_certs(void)
1170-{
1171- int err = 0;
1172- char hit[41];
1173- FILE *conf_file;
1174- struct local_host_id *entry;
1175- char hostname[HIP_HOST_ID_HOSTNAME_LEN_MAX];
1176-
1177- HIP_IFEL(gethostname(hostname, sizeof(hostname)), -1,
1178- "gethostname failed\n");
1179-
1180- conf_file = fopen(HIP_CERT_CONF_PATH, "r");
1181- if (!conf_file) {
1182- HIP_DEBUG("Configuration file did NOT exist creating it and "
1183- "filling it with default information\n");
1184- /* Fetch the first RSA HIT */
1185- entry = hip_get_hostid_entry_by_lhi_and_algo(NULL, HIP_HI_RSA, -1);
1186- if (entry == NULL) {
1187- HIP_DEBUG("Failed to get the first RSA HI");
1188- goto out_err;
1189- }
1190- hip_in6_ntop(&entry->hit, hit);
1191- conf_file = fopen(HIP_CERT_CONF_PATH, "w+");
1192- fprintf(conf_file,
1193- "# Section containing SPKI related information\n"
1194- "#\n"
1195- "# issuerhit = what hit is to be used when signing\n"
1196- "# days = how long is this key valid\n"
1197- "\n"
1198- "[ hip_spki ]\n"
1199- "issuerhit = %s\n"
1200- "days = %d\n"
1201- "\n"
1202- "# Section containing HIP related information\n"
1203- "#\n"
1204- "# issuerhit = what hit is to be used when signing\n"
1205- "# days = how long is this key valid\n"
1206- "\n"
1207- "[ hip_x509v3 ]\n"
1208- "issuerhit = %s\n"
1209- "days = %d\n"
1210- "\n"
1211- "#Section containing the name section for the x509v3 issuer name"
1212- "\n"
1213- "[ hip_x509v3_name ]\n"
1214- "issuerhit = %s\n"
1215- "\n"
1216- "# Uncomment this section to add x509 extensions\n"
1217- "# to the certificate\n"
1218- "#\n"
1219- "# DO NOT use subjectAltName, issuerAltName or\n"
1220- "# basicConstraints implementation uses them already\n"
1221- "# All other extensions are allowed\n"
1222- "\n"
1223- "# [ hip_x509v3_extensions ]\n",
1224- hit, HIP_CERT_INIT_DAYS,
1225- hit, HIP_CERT_INIT_DAYS,
1226- hit /* TODO SAMU: removed because not used:*/ /*, hostname*/);
1227- } else {
1228- HIP_DEBUG("Configuration file existed exiting init_certs\n");
1229- }
1230- fclose(conf_file);
1231-
1232-out_err:
1233- return err;
1234-}
1235-
1236 static void init_packet_types(void)
1237 {
1238 lmod_register_packet_type(HIP_I1, "HIP_I1");
1239@@ -894,7 +819,7 @@
1240 */
1241 int hipd_init(const uint64_t flags)
1242 {
1243- int err = 0, certerr = 0, i, j;
1244+ int err = 0, i, j;
1245 int killold = (flags & HIPD_START_KILL_OLD) > 0;
1246 unsigned int mtu_val = HIP_HIT_DEV_MTU;
1247 char str[64];
1248@@ -1035,12 +960,6 @@
1249 return -1;
1250 }
1251
1252- certerr = 0;
1253- certerr = init_certs();
1254- if (certerr < 0) {
1255- HIP_DEBUG("Initializing cert configuration file returned error\n");
1256- }
1257-
1258 /* Service initialization. */
1259 hip_init_services();
1260
1261
1262=== modified file 'hipd/input.c'
1263--- hipd/input.c 2012-02-17 10:45:47 +0000
1264+++ hipd/input.c 2012-02-20 21:55:24 +0000
1265@@ -73,7 +73,6 @@
1266 #include "netdev.h"
1267 #include "opp_mode.h"
1268 #include "output.h"
1269-#include "pisa.h"
1270 #include "pkt_handling.h"
1271 #include "registration.h"
1272 #include "input.h"
1273
1274=== modified file 'hipd/output.c'
1275--- hipd/output.c 2012-02-15 17:37:10 +0000
1276+++ hipd/output.c 2012-02-20 21:55:24 +0000
1277@@ -65,7 +65,6 @@
1278 #include "hiprelay.h"
1279 #include "nat.h"
1280 #include "netdev.h"
1281-#include "pisa.h"
1282 #include "registration.h"
1283 #include "output.h"
1284
1285
1286=== removed file 'hipd/pisa.c'
1287--- hipd/pisa.c 2011-10-25 21:14:16 +0000
1288+++ hipd/pisa.c 1970-01-01 00:00:00 +0000
1289@@ -1,83 +0,0 @@
1290-/*
1291- * Copyright (c) 2010 Aalto University and RWTH Aachen University.
1292- *
1293- * Permission is hereby granted, free of charge, to any person
1294- * obtaining a copy of this software and associated documentation
1295- * files (the "Software"), to deal in the Software without
1296- * restriction, including without limitation the rights to use,
1297- * copy, modify, merge, publish, distribute, sublicense, and/or sell
1298- * copies of the Software, and to permit persons to whom the
1299- * Software is furnished to do so, subject to the following
1300- * conditions:
1301- *
1302- * The above copyright notice and this permission notice shall be
1303- * included in all copies or substantial portions of the Software.
1304- *
1305- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
1306- * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
1307- * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
1308- * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
1309- * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
1310- * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
1311- * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
1312- * OTHER DEALINGS IN THE SOFTWARE.
1313- */
1314-
1315-/**
1316- * @file
1317- * This file contains functions that are specific to PISA. They deal with the
1318- * certificate loading.
1319- *
1320- * @brief Functions for certificate loading
1321- */
1322-
1323-#include <stdio.h>
1324-#include <stdlib.h>
1325-#include <string.h>
1326-
1327-#include "config.h"
1328-#include "lib/core/debug.h"
1329-#include "hipd.h"
1330-#include "pisa.h"
1331-
1332-#define CERT_MAX_SIZE 1024
1333-
1334-static char *midauth_cert = NULL;
1335-
1336-/**
1337- * Load a certificate from the file HIPL_SYSCONFDIR/cert and store it in memory
1338- *
1339- * @return 0 on success
1340- */
1341-static int pisa_load_certificate(void)
1342-{
1343- FILE *f = NULL;
1344-
1345- free(midauth_cert);
1346- midauth_cert = calloc(1, CERT_MAX_SIZE);
1347-
1348- if (!(f = fopen(HIPL_SYSCONFDIR "/cert", "r"))) {
1349- HIP_ERROR("Could not open certificate file.\n");
1350- return -1;
1351- }
1352-
1353- if (fread(midauth_cert, CERT_MAX_SIZE - 1, 1, f) == 0) {
1354- perror("fread returned 0");
1355- }
1356- fclose(f);
1357- return 0;
1358-}
1359-
1360-/**
1361- * Load a certificate from disk and return a pointer to the global
1362- * variable containing it.
1363- *
1364- * @see pisa_load_certificate*
1365- *
1366- * @return pointer to midauth_cert
1367- */
1368-char *hip_pisa_get_certificate(void)
1369-{
1370- pisa_load_certificate();
1371- return midauth_cert;
1372-}
1373
1374=== removed file 'hipd/pisa.h'
1375--- hipd/pisa.h 2011-11-25 17:56:24 +0000
1376+++ hipd/pisa.h 1970-01-01 00:00:00 +0000
1377@@ -1,44 +0,0 @@
1378-/*
1379- * Copyright (c) 2010 Aalto University and RWTH Aachen University.
1380- *
1381- * Permission is hereby granted, free of charge, to any person
1382- * obtaining a copy of this software and associated documentation
1383- * files (the "Software"), to deal in the Software without
1384- * restriction, including without limitation the rights to use,
1385- * copy, modify, merge, publish, distribute, sublicense, and/or sell
1386- * copies of the Software, and to permit persons to whom the
1387- * Software is furnished to do so, subject to the following
1388- * conditions:
1389- *
1390- * The above copyright notice and this permission notice shall be
1391- * included in all copies or substantial portions of the Software.
1392- *
1393- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
1394- * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
1395- * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
1396- * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
1397- * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
1398- * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
1399- * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
1400- * OTHER DEALINGS IN THE SOFTWARE.
1401- */
1402-
1403-/**
1404- * @file
1405- * This file contains function declarations specific to PISA. They deal with the
1406- * certificate loading.
1407- *
1408- * @brief Functions declarations for certificate loading
1409- */
1410-
1411-#ifndef HIPL_HIPD_PISA_H
1412-#define HIPL_HIPD_PISA_H
1413-
1414-/**
1415- * Get the certificate text that will be appended to R2 and U2 packets
1416- *
1417- * @return pointer to the certificate text
1418- */
1419-char *hip_pisa_get_certificate(void);
1420-
1421-#endif /* HIPL_HIPD_PISA_H */
1422
1423=== modified file 'hipd/user.c'
1424--- hipd/user.c 2012-02-15 17:37:10 +0000
1425+++ hipd/user.c 2012-02-20 21:55:24 +0000
1426@@ -65,7 +65,6 @@
1427 #include "lib/tool/nlink.h"
1428 #include "config.h"
1429 #include "accessor.h"
1430-#include "cert.h"
1431 #include "close.h"
1432 #include "cookie.h"
1433 #include "esp_prot_anchordb.h"
1434@@ -240,7 +239,7 @@
1435 {
1436 const hip_hit_t *src_hit = NULL, *dst_hit = NULL;
1437 struct hip_hadb_state *entry = NULL;
1438- int err = 0, msg_type = 0, reti = 0;
1439+ int err = 0, msg_type = 0;
1440 int access_ok = 0, is_root = 0, name_len;
1441 const struct hip_tlv_common *param = NULL;
1442 const struct hip_transformation_order *transorder;
1443@@ -359,40 +358,6 @@
1444 dst_hit = hip_get_param_contents(msg, HIP_PARAM_HIT);
1445 hip_dec_cookie_difficulty();
1446 break;
1447- case HIP_MSG_CERT_SPKI_VERIFY:
1448- {
1449- HIP_DEBUG("Got an request to verify SPKI cert\n");
1450- reti = hip_cert_spki_verify(msg);
1451- HIP_IFEL(reti, -1, "Verifying SPKI cert returned an error\n");
1452- HIP_DEBUG("SPKI cert verified sending it back to requester\n");
1453- }
1454- break;
1455- case HIP_MSG_CERT_SPKI_SIGN:
1456- {
1457- HIP_DEBUG("Got an request to sign SPKI cert sequence\n");
1458- reti = hip_cert_spki_sign(msg);
1459- HIP_IFEL(reti, -1, "Signing SPKI cert returned an error\n");
1460- HIP_DEBUG("SPKI cert signed sending it back to requester\n");
1461- }
1462- break;
1463- case HIP_MSG_CERT_X509V3_SIGN:
1464- {
1465- HIP_DEBUG("Got an request to sign X509v3 cert\n");
1466- reti = hip_cert_x509v3_handle_request_to_sign(msg);
1467- HIP_IFEL(reti, -1, "Signing of x509v3 cert returned an error\n");
1468- HIP_DEBUG("X509v3 cert signed sending it back to requester\n");
1469- }
1470- break;
1471- case HIP_MSG_CERT_X509V3_VERIFY:
1472- {
1473- HIP_DEBUG("Got an request to verify X509v3 cert\n");
1474- reti = hip_cert_x509v3_handle_request_to_verify(msg);
1475- HIP_IFEL(reti, -1, "Verification of x509v3 cert "
1476- "returned an error\n");
1477- HIP_DEBUG("X509v3 verification ended "
1478- "sending it back to requester\n");
1479- }
1480- break;
1481 case HIP_MSG_TRANSFORM_ORDER:
1482 {
1483 err = 0;
1484
1485=== modified file 'hipfw/conntrack.c'
1486--- hipfw/conntrack.c 2012-02-17 18:01:18 +0000
1487+++ hipfw/conntrack.c 2012-02-20 21:55:24 +0000
1488@@ -72,8 +72,8 @@
1489 #include "hipfw.h"
1490 #include "helpers.h"
1491 #include "hslist.h"
1492-#include "pisa.h"
1493 #include "reinject.h"
1494+#include "midauth.h"
1495
1496
1497 static struct dlist *hip_list = NULL;
1498@@ -1386,7 +1386,7 @@
1499 return 0;
1500 }
1501
1502- esp_tuple->spi = ntohl(esp_info->new_spi);
1503+ esp_tuple->spi = ntohl(esp_info->new_spi);
1504 esp_tuple->spi_update_id = seq->update_id;
1505
1506 HIP_IFEL(!update_esp_dest_addr(locator, seq, esp_tuple),
1507@@ -1400,7 +1400,7 @@
1508 return 0;
1509 }
1510
1511- esp_tuple->spi = ntohl(esp_info->new_spi);
1512+ esp_tuple->spi = ntohl(esp_info->new_spi);
1513 esp_tuple->spi_update_id = seq->update_id;
1514 } else if (locator && seq) {
1515 HIP_DEBUG("locator and seq\n");
1516
1517=== modified file 'hipfw/hipfw.c'
1518--- hipfw/hipfw.c 2011-11-25 16:40:40 +0000
1519+++ hipfw/hipfw.c 2012-02-20 21:55:24 +0000
1520@@ -87,7 +87,6 @@
1521 #include "helpers.h"
1522 #include "lsi.h"
1523 #include "midauth.h"
1524-#include "pisa.h"
1525 #include "port_bindings.h"
1526 #include "reinject.h"
1527 #include "rewrite.h"
1528@@ -1885,12 +1884,6 @@
1529 continue;
1530 }
1531
1532-#ifdef CONFIG_HIP_PISA
1533- if (use_midauth) {
1534- pisa_check_for_random_update();
1535- }
1536-#endif
1537-
1538 if (FD_ISSET(h4->fd, &read_fdset)) {
1539 HIP_DEBUG("received IPv4 packet from iptables queue\n");
1540 err = fw_handle_packet(buf, h4, 4, &ctx);
1541
1542=== removed file 'hipfw/pisa.c'
1543--- hipfw/pisa.c 2011-11-25 13:52:20 +0000
1544+++ hipfw/pisa.c 1970-01-01 00:00:00 +0000
1545@@ -1,575 +0,0 @@
1546-/*
1547- * Copyright (c) 2010 Aalto University and RWTH Aachen University.
1548- *
1549- * Permission is hereby granted, free of charge, to any person
1550- * obtaining a copy of this software and associated documentation
1551- * files (the "Software"), to deal in the Software without
1552- * restriction, including without limitation the rights to use,
1553- * copy, modify, merge, publish, distribute, sublicense, and/or sell
1554- * copies of the Software, and to permit persons to whom the
1555- * Software is furnished to do so, subject to the following
1556- * conditions:
1557- *
1558- * The above copyright notice and this permission notice shall be
1559- * included in all copies or substantial portions of the Software.
1560- *
1561- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
1562- * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
1563- * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
1564- * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
1565- * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
1566- * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
1567- * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
1568- * OTHER DEALINGS IN THE SOFTWARE.
1569- */
1570-
1571-/**
1572- * @file
1573- * This file contains PISA specific functions for the firewall. The basic idea
1574- * is to modify the HIP messages and manage state for allowed connections to
1575- * allow or reject associated ESP traffic.
1576- *
1577- * @brief PISA functions for the firewall
1578- */
1579-
1580-#define _BSD_SOURCE
1581-
1582-#include <stdint.h>
1583-#include <stdio.h>
1584-#include <stdlib.h>
1585-#include <string.h>
1586-#include <time.h>
1587-#include <arpa/inet.h>
1588-#include <netinet/in.h>
1589-#include <linux/netfilter.h>
1590-#include <openssl/hmac.h>
1591-
1592-#include "config.h"
1593-#include "lib/core/builder.h"
1594-#include "lib/core/certtools.h"
1595-#include "lib/core/crypto.h"
1596-#include "lib/core/debug.h"
1597-#include "lib/core/ife.h"
1598-#include "lib/core/performance.h"
1599-#include "lib/core/prefix.h"
1600-#include "modules/midauth/hipd/midauth.h"
1601-#include "conntrack.h"
1602-#include "hipfw_defines.h"
1603-#include "midauth.h"
1604-#include "pisa_cert.h"
1605-#include "pisa.h"
1606-
1607-
1608-#define PISA_RANDOM_LEN 16
1609-#define PISA_PUZZLE_SEED 0xDEADC0DE
1610-#define PISA_PUZZLE_OPAQUE_LEN (4 + HIP_AH_SHA_LEN)
1611-
1612-/* pisa_check_for_random_update is called at least every PISA_RANDOM_TTL
1613- * seconds. Worst case timer resolution depends on the timeout in the select
1614- * call */
1615-#define PISA_RANDOM_TTL 2.0
1616-
1617-static char pisa_random_data[2][PISA_RANDOM_LEN];
1618-static struct in6_addr community_operator_hit;
1619-
1620-/* @todo make this configurable, issuer HIT */
1621-#define CO_HIT "2001:001a:b1b0:0aad:0f92:15ca:280c:9430"
1622-#define CO_HIT_FILE HIPL_SYSCONFDIR "/co_hit"
1623-
1624-/**
1625- * Generate a new random number and shift the old one down.
1626- */
1627-static void pisa_generate_random(void)
1628-{
1629- void *p0, *p1;
1630-
1631- p0 = &pisa_random_data[0][0];
1632- p1 = &pisa_random_data[1][0];
1633-
1634- memcpy(p0, p1, PISA_RANDOM_LEN);
1635- get_random_bytes(p1, PISA_RANDOM_LEN);
1636-}
1637-
1638-/**
1639- * Reads out the HIT of the Community-Operator
1640- * from file CO_HIT_FILE
1641- * @param hit A pointer to the char where the HIT should be stored
1642- * @return 1-> success
1643- * @return 0-> error
1644- */
1645-static int pisa_read_communit_operator_hit(char *hit)
1646-{
1647- FILE *f;
1648- char *eofline;
1649-
1650- f = fopen(CO_HIT_FILE, "r");
1651-
1652- if (f == NULL) {
1653- return 0;
1654- }
1655-
1656- if (fgets(hit, INET6_ADDRSTRLEN, f) != NULL) {
1657- eofline = strchr(hit, '\n');
1658- if (eofline) {
1659- *eofline = '\0';
1660- }
1661- } else {
1662- HIP_ERROR("Fgets failed");
1663- }
1664- fclose(f);
1665-
1666- return 1;
1667-}
1668-
1669-void pisa_check_for_random_update(void)
1670-{
1671- static time_t lastupdate = 0;
1672- time_t now;
1673-
1674- time(&now);
1675- if (difftime(now, lastupdate) > PISA_RANDOM_TTL) {
1676- pisa_generate_random();
1677- lastupdate = now;
1678- }
1679-}
1680-
1681-/**
1682- * Appends HMAC/SHA1 to a block of data.
1683- *
1684- * @param hit1 first HIT
1685- * @param hit2 second HIT
1686- * @param rnd which random number to use, either 0 or 1
1687- * @param data pointer to buffer for data and the HMAC
1688- * @param data_len length of data
1689- * @return 0 on success
1690- */
1691-static int pisa_append_hmac(struct in6_addr *hit1, struct in6_addr *hit2,
1692- int rnd, void *data, int data_len)
1693-{
1694- uint8_t key[32 + PISA_RANDOM_LEN];
1695- int err = 0;
1696- unsigned int len = HIP_AH_SHA_LEN;
1697-
1698- /* sanity checks for arguments */
1699- HIP_IFEL(data == NULL, -1, "No data given.\n");
1700- HIP_IFEL(hit1 == NULL, -1, "No first HIT given.\n");
1701- HIP_IFEL(hit2 == NULL, -1, "No second HIT given.\n");
1702- HIP_IFEL(data_len < 1, -1, "Data has invalid length.\n");
1703- HIP_IFEL(rnd != 0 && rnd != 1, -1, "Random ID is neither 0 nor 1.\n");
1704-
1705- /* The key for HMAC/SHA1 consists of:
1706- * 16 bytes HIT1
1707- * 16 bytes HIT2
1708- * PISA_RANDOM_LEN bytes pisa_random_data
1709- */
1710-
1711- ipv6_addr_copy((struct in6_addr *) (key + 0), hit1);
1712- ipv6_addr_copy((struct in6_addr *) (key + 16), hit2);
1713- memcpy(key + 32, &pisa_random_data[rnd][0], PISA_RANDOM_LEN);
1714-
1715- HMAC(EVP_sha1(), key, 32 + PISA_RANDOM_LEN, data, data_len,
1716- (uint8_t *) data + data_len, &len);
1717-
1718-out_err:
1719- return err;
1720-}
1721-
1722-/**
1723- * Insert a PISA puzzle into a packet.
1724- *
1725- * @param ctx context of the packet where the puzzle will be inserted
1726- * @return success (0) or failure
1727- */
1728-static int pisa_insert_puzzle(struct hip_fw_context *ctx)
1729-{
1730- uint8_t opaque[PISA_PUZZLE_OPAQUE_LEN];
1731-
1732- struct hip_common *hip = ctx->transport_hdr.hip;
1733- int seed = PISA_PUZZLE_SEED;
1734-
1735- memcpy(&opaque, &seed, 4);
1736-
1737- /* here we switch order of initiator and receiver to obtain a
1738- * different SHA1 hash */
1739- pisa_append_hmac(&hip->hitr, &hip->hits, 1, &opaque, 4);
1740-
1741- return midauth_add_challenge_request(ctx, 3, 4, opaque, PISA_PUZZLE_OPAQUE_LEN);
1742-}
1743-
1744-/**
1745- * Check the validity of a PISA challenge_response.
1746- *
1747- * @param ctx context of the packet with the puzzle to check
1748- * @return pointer to the puzzle we accepted or NULL at failure
1749- */
1750-static struct hip_challenge_response *pisa_check_challenge_response(struct hip_fw_context *ctx)
1751-{
1752- struct hip_challenge_response *response;
1753- struct hip_common *hip = ctx->transport_hdr.hip;
1754- uint8_t hash[2][PISA_PUZZLE_OPAQUE_LEN];
1755- int seed = PISA_PUZZLE_SEED;
1756-
1757- memcpy(&hash[0][0], &seed, 4);
1758- memcpy(&hash[1][0], &seed, 4);
1759-
1760- pisa_append_hmac(&hip->hits, &hip->hitr, 0, &hash[0], 4);
1761- pisa_append_hmac(&hip->hits, &hip->hitr, 1, &hash[1], 4);
1762-
1763- response = hip_get_param_readwrite(hip, HIP_PARAM_CHALLENGE_RESPONSE);
1764-
1765- while (response) {
1766- /* loop over all HIP_PARAM_CHALLENGE_RESPONSE */
1767- if (hip_get_param_type(response) != HIP_PARAM_CHALLENGE_RESPONSE) {
1768- break;
1769- }
1770- if ((!memcmp(response->opaque, &hash[1][0], PISA_PUZZLE_OPAQUE_LEN)) ||
1771- (!memcmp(response->opaque, &hash[0][0], PISA_PUZZLE_OPAQUE_LEN))) {
1772- if (!midauth_verify_challenge_response(response,
1773- hip->hits,
1774- hip->hitr)) {
1775- return response;
1776- }
1777- }
1778-
1779- response = (struct hip_challenge_response *)
1780- hip_get_next_param_readwrite(hip,
1781- (struct hip_tlv_common *) response);
1782- }
1783-
1784- return NULL;
1785-}
1786-
1787-/**
1788- * Check the certificate of the packet.
1789- *
1790- * @param ctx context of the packet with the certificate to check
1791- * @return success (0) or failure
1792- */
1793-static int pisa_check_certificate(struct hip_fw_context *ctx)
1794-{
1795- struct hip_common *hip = ctx->transport_hdr.hip;
1796- const struct hip_cert *cert;
1797- struct hip_cert_spki_info ci;
1798- struct pisa_cert pc;
1799- char *buf = NULL;
1800- int err = 0, len;
1801- time_t now = time(NULL);
1802-
1803- cert = hip_get_param(hip, HIP_PARAM_CERT);
1804- HIP_IFEL(cert == NULL, -1, "No certificate found.\n");
1805-
1806- len = ntohs(cert->length);
1807- buf = calloc(1, len);
1808- memcpy(buf, cert + 1, len);
1809-
1810- HIP_IFEL(hip_cert_spki_char2certinfo(buf, &ci), -1,
1811- "Certificate could not be parsed.\n");
1812- HIP_IFEL(hip_cert_spki_lib_verify(&ci), -1,
1813- "Certificate could not be verified.\n");
1814-
1815- pisa_split_cert(ci.cert, &pc);
1816-
1817- /* Three conditions must be fulfilled for a certificate to be valid:
1818- *
1819- * - The current time on the middlebox must be in the before/after
1820- * interval
1821- * - The certificate must be issued by the community operator (i.e.
1822- * the CO HIT must be used by the issuer)
1823- * - The host sending the certificate must be the one mentioned in
1824- * the certificate
1825- */
1826- HIP_IFEL(now < pc.not_before, -1,
1827- "Certificate is not valid yet.\n");
1828- HIP_IFEL(now > pc.not_after, -1,
1829- "Certificate has expired.\n");
1830-
1831-
1832- HIP_IFEL(ipv6_addr_cmp(&pc.hit_issuer, &community_operator_hit) != 0,
1833- -1, "Certificate not issued by the community operator.\n");
1834- HIP_IFEL(ipv6_addr_cmp(&pc.hit_subject, &hip->hits) != 0, -1,
1835- "Certificate does not belong to subject.\n");
1836-
1837- HIP_INFO("Certificate successfully verified.\n");
1838-
1839-out_err:
1840- free(buf);
1841- return err;
1842-}
1843-
1844-/**
1845- * Accept a connection via PISA. Update firewall to allow data packets to
1846- * pass through.
1847- *
1848- * @param ctx context of the packet that belongs to that connection
1849- */
1850-static void pisa_accept_connection(const struct hip_fw_context *ctx)
1851-{
1852- struct hip_common *hip = ctx->transport_hdr.hip;
1853- struct tuple *t = get_tuple_by_hits(&hip->hits, &hip->hitr);
1854-
1855- if (t) {
1856- t->connection->pisa_state = PISA_STATE_ALLOW;
1857- HIP_INFO("PISA accepted the connection.\n");
1858- hip_fw_manage_all_esp_tuples(t, true);
1859- } else {
1860- HIP_ERROR("Connection not found.\n");
1861- }
1862-}
1863-
1864-/**
1865- * Remove a connection from the list of accepted connections based on the hits
1866- * of a packet.
1867- *
1868- * @param ctx context of the packet that contains HITs of the connection
1869- */
1870-static void pisa_remove_connection(const struct hip_fw_context *ctx)
1871-{
1872- struct hip_common *hip = ctx->transport_hdr.hip;
1873- struct tuple *t = get_tuple_by_hits(&hip->hits, &hip->hitr);
1874-
1875- if (t) {
1876- t->connection->pisa_state = PISA_STATE_DISALLOW;
1877- HIP_INFO("PISA removed the connection.\n");
1878- hip_fw_manage_all_esp_tuples(t, false);
1879- } else {
1880- HIP_ERROR("Connection not found.\n");
1881- }
1882-}
1883-
1884-/**
1885- * Reject a connection via PISA. Update firewall to allow no data packets
1886- * to pass through.
1887- *
1888- * @param ctx context of the packet that belongs to that connection
1889- */
1890-static void pisa_reject_connection(const struct hip_fw_context *ctx)
1891-{
1892- HIP_INFO("PISA rejected the connection.\n");
1893- pisa_remove_connection(ctx);
1894-}
1895-
1896-/**
1897- * Dummy function, necessary only for performance measurements.
1898- *
1899- * @param ctx context of the packet containing the I1
1900- * @return NF_ACCEPT verdict
1901- */
1902-static int pisa_handler_i1(UNUSED struct hip_fw_context *ctx)
1903-{
1904-#ifdef CONFIG_HIP_PERFORMANCE
1905- HIP_DEBUG("Start PERF_BASE, PERF_I1\n");
1906- hip_perf_start_benchmark(perf_set, PERF_BASE);
1907- hip_perf_start_benchmark(perf_set, PERF_I1);
1908-#endif
1909-
1910-#ifdef CONFIG_HIP_PERFORMANCE
1911- HIP_DEBUG("Stop and write PERF_I1\n");
1912- hip_perf_stop_benchmark(perf_set, PERF_I1);
1913- hip_perf_write_benchmark(perf_set, PERF_I1);
1914-#endif
1915-
1916- return NF_ACCEPT;
1917-}
1918-
1919-/**
1920- * Dummy function, necessary only for performance measurements.
1921- *
1922- * @param ctx context of the packet containing the R1
1923- * @return NF_ACCEPT verdict
1924- */
1925-static int pisa_handler_r1(UNUSED struct hip_fw_context *ctx)
1926-{
1927-#ifdef CONFIG_HIP_PERFORMANCE
1928- HIP_DEBUG("Start PERF_R1\n");
1929- hip_perf_start_benchmark(perf_set, PERF_R1);
1930-#endif
1931-
1932-#ifdef CONFIG_HIP_PERFORMANCE
1933- HIP_DEBUG("Stop and write PERF_R1\n");
1934- hip_perf_stop_benchmark(perf_set, PERF_R1);
1935- hip_perf_write_benchmark(perf_set, PERF_R1);
1936-#endif
1937-
1938- return NF_ACCEPT;
1939-}
1940-
1941-/**
1942- * Insert a PISA puzzle into the I2 packet.
1943- *
1944- * @param ctx context of the packet to modify
1945- * @return NF_ACCEPT verdict
1946- */
1947-static int pisa_handler_i2(struct hip_fw_context *ctx)
1948-{
1949-#ifdef CONFIG_HIP_PERFORMANCE
1950- HIP_DEBUG("Start PERF_I2\n");
1951- hip_perf_start_benchmark(perf_set, PERF_I2);
1952-#endif
1953- pisa_insert_puzzle(ctx);
1954-
1955-#ifdef CONFIG_HIP_PERFORMANCE
1956- HIP_DEBUG("Stop and write PERF_I2\n");
1957- hip_perf_stop_benchmark(perf_set, PERF_I2);
1958- hip_perf_write_benchmark(perf_set, PERF_I2);
1959-#endif
1960-
1961- return NF_ACCEPT;
1962-}
1963-
1964-/**
1965- * Check for a PISA puzzle, a valid signature and a valid
1966- * certificate in the R2 packet.
1967- *
1968- * @param ctx context of the packet to check
1969- * @return verdict, either NF_ACCEPT or NF_DROP
1970- */
1971-static int pisa_handler_r2(struct hip_fw_context *ctx)
1972-{
1973- int verdict = NF_DROP, sig = 0, cert = 0;
1974- struct hip_challenge_response *solution = NULL;
1975-
1976-#ifdef CONFIG_HIP_PERFORMANCE
1977- HIP_DEBUG("Start PERF_R2\n");
1978- hip_perf_start_benchmark(perf_set, PERF_R2);
1979-#endif
1980-
1981- solution = pisa_check_challenge_response(ctx);
1982- cert = pisa_check_certificate(ctx);
1983-
1984- if (solution == NULL || sig != 0 || cert != 0) {
1985- /* disallow further communication if either nonce, solution,
1986- * signature or certificate were not correct */
1987- pisa_reject_connection(ctx);
1988- verdict = NF_DROP;
1989- } else {
1990- /* allow futher communication otherwise */
1991- pisa_accept_connection(ctx);
1992- verdict = NF_ACCEPT;
1993- }
1994-
1995-#ifdef CONFIG_HIP_PERFORMANCE
1996- HIP_DEBUG("Stop and write PERF_R2, PERF_BASE\n");
1997- hip_perf_stop_benchmark(perf_set, PERF_R2);
1998- hip_perf_stop_benchmark(perf_set, PERF_BASE);
1999- hip_perf_write_benchmark(perf_set, PERF_R2);
2000- hip_perf_write_benchmark(perf_set, PERF_BASE);
2001-#endif
2002-
2003- return verdict;
2004-}
2005-
2006-/**
2007- * Insert a PISA nonce and a PISA puzzle into the U1 packet.
2008- *
2009- * @param ctx context of the packet to modify
2010- * @return NF_ACCEPT verdict
2011- */
2012-static int pisa_handler_u1(struct hip_fw_context *ctx)
2013-{
2014- pisa_insert_puzzle(ctx);
2015-
2016- return NF_ACCEPT;
2017-}
2018-
2019-/**
2020- * Check for a PISA nonce, a PISA puzzle, a valid signature and a valid
2021- * certificate in the U2 packet.
2022- *
2023- * @param ctx context of the packet to check
2024- * @return verdict, either NF_ACCEPT or NF_DROP
2025- */
2026-static int pisa_handler_u2(struct hip_fw_context *ctx)
2027-{
2028- int verdict = NF_DROP;
2029- int sig = 0;
2030- int cert = 0;
2031- struct hip_challenge_response *solution = NULL;
2032-
2033- solution = pisa_check_challenge_response(ctx);
2034- cert = pisa_check_certificate(ctx);
2035-
2036- if (solution == NULL || sig != 0 || cert != 0) {
2037- HIP_DEBUG("U2 packet did not match criteria: "
2038- "solution %p, signature %i, cert %i\n",
2039- solution, sig, cert);
2040- verdict = NF_DROP;
2041- } else {
2042- /* packet was ok, insert another puzzle */
2043- pisa_insert_puzzle(ctx);
2044- verdict = NF_ACCEPT;
2045- }
2046-
2047- return verdict;
2048-}
2049-
2050-/**
2051- * Check for a PISA nonce and a valid signature in the U3 packet.
2052- *
2053- * @param ctx context of the packet to check
2054- * @return verdict, either NF_ACCEPT or NF_DROP
2055- */
2056-static int pisa_handler_u3(struct hip_fw_context *ctx)
2057-{
2058- int verdict = NF_DROP;
2059- int sig = 0;
2060- struct hip_challenge_response *solution = NULL;
2061-
2062- solution = pisa_check_challenge_response(ctx);
2063-
2064- if (solution == NULL || sig != 0) {
2065- HIP_DEBUG("U2 packet did not match criteria: "
2066- "solution %p\n",
2067- solution);
2068- pisa_reject_connection(ctx);
2069- verdict = NF_DROP;
2070- } else {
2071- pisa_accept_connection(ctx);
2072- verdict = NF_ACCEPT;
2073- }
2074- return verdict;
2075-}
2076-
2077-/**
2078- * Handle CLOSE_ACK packet. Remove the connection from the list of accepted
2079- * connections
2080- *
2081- * @param ctx context of the packet
2082- * @return verdict, either NF_ACCEPT or NF_DROP
2083- */
2084-static int pisa_handler_close_ack(struct hip_fw_context *ctx)
2085-{
2086- pisa_remove_connection(ctx);
2087- return NF_ACCEPT;
2088-}
2089-
2090-/**
2091- * Initialize basic PISA functionality
2092- *
2093- * @param h function pointers for packet handlers
2094- */
2095-void pisa_init(struct midauth_handlers *h)
2096-{
2097- char hit[INET6_ADDRSTRLEN];
2098- h->i1 = pisa_handler_i1;
2099- h->r1 = pisa_handler_r1;
2100- h->i2 = pisa_handler_i2;
2101- h->r2 = pisa_handler_r2;
2102- h->u1 = pisa_handler_u1;
2103- h->u2 = pisa_handler_u2;
2104- h->u3 = pisa_handler_u3;
2105- h->close = midauth_handler_accept;
2106- h->close_ack = pisa_handler_close_ack;
2107-
2108- pisa_generate_random();
2109- pisa_generate_random();
2110-
2111- if (!pisa_read_communit_operator_hit(hit)) {
2112- hit[0] = '\0';
2113- HIP_ERROR("Could not load Communit-Operator HIT from file %s\n",
2114- CO_HIT_FILE);
2115- }
2116-
2117- if (inet_pton(AF_INET6, hit, &community_operator_hit) <= 0) {
2118- HIP_ERROR("Coult not parse Community-Operator HIT\n");
2119- }
2120-}
2121
2122=== removed file 'hipfw/pisa.h'
2123--- hipfw/pisa.h 2011-11-25 13:52:20 +0000
2124+++ hipfw/pisa.h 1970-01-01 00:00:00 +0000
2125@@ -1,48 +0,0 @@
2126-/*
2127- * Copyright (c) 2010 Aalto University and RWTH Aachen University.
2128- *
2129- * Permission is hereby granted, free of charge, to any person
2130- * obtaining a copy of this software and associated documentation
2131- * files (the "Software"), to deal in the Software without
2132- * restriction, including without limitation the rights to use,
2133- * copy, modify, merge, publish, distribute, sublicense, and/or sell
2134- * copies of the Software, and to permit persons to whom the
2135- * Software is furnished to do so, subject to the following
2136- * conditions:
2137- *
2138- * The above copyright notice and this permission notice shall be
2139- * included in all copies or substantial portions of the Software.
2140- *
2141- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
2142- * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
2143- * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
2144- * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
2145- * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
2146- * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
2147- * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
2148- * OTHER DEALINGS IN THE SOFTWARE.
2149- */
2150-
2151-#ifndef HIPL_HIPFW_PISA_H
2152-#define HIPL_HIPFW_PISA_H
2153-
2154-#include "midauth.h"
2155-
2156-#define PISA_STATE_DISALLOW 0
2157-#define PISA_STATE_ALLOW 1
2158-
2159-#ifdef CONFIG_HIP_PISA
2160-/**
2161- * Register PISA handlers with midauth and initialize data structures.
2162- *
2163- * @param h pointer to the handlers
2164- */
2165-void pisa_init(struct midauth_handlers *h);
2166-#endif
2167-
2168-/**
2169- * Check if a new random number is necessary.
2170- */
2171-void pisa_check_for_random_update(void);
2172-
2173-#endif /* HIPL_HIPFW_PISA_H */
2174
2175=== removed file 'hipfw/pisa_cert.c'
2176--- hipfw/pisa_cert.c 2011-08-15 14:11:56 +0000
2177+++ hipfw/pisa_cert.c 1970-01-01 00:00:00 +0000
2178@@ -1,205 +0,0 @@
2179-/*
2180- * Copyright (c) 2010 Aalto University and RWTH Aachen University.
2181- *
2182- * Permission is hereby granted, free of charge, to any person
2183- * obtaining a copy of this software and associated documentation
2184- * files (the "Software"), to deal in the Software without
2185- * restriction, including without limitation the rights to use,
2186- * copy, modify, merge, publish, distribute, sublicense, and/or sell
2187- * copies of the Software, and to permit persons to whom the
2188- * Software is furnished to do so, subject to the following
2189- * conditions:
2190- *
2191- * The above copyright notice and this permission notice shall be
2192- * included in all copies or substantial portions of the Software.
2193- *
2194- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
2195- * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
2196- * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
2197- * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
2198- * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
2199- * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
2200- * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
2201- * OTHER DEALINGS IN THE SOFTWARE.
2202- */
2203-
2204-/**
2205- * @file
2206- * This file deals with the PISA specific handling of SPKI certificates. The
2207- * certificate is parsed and split into small chunks.
2208- *
2209- * @brief PISA handling for SPKI certificates
2210- */
2211-
2212-#define _BSD_SOURCE
2213-
2214-#include <string.h>
2215-#include <time.h>
2216-#include <arpa/inet.h>
2217-#include <netinet/in.h>
2218-#include <sys/types.h>
2219-
2220-#include "pisa_cert.h"
2221-
2222-
2223-/**
2224- * Extract parts of a SPKI certificate.
2225- *
2226- * @param cert pointer to the certificate text or part of a certificate text
2227- * @param name pointer to the pattern we are looking for
2228- * @param r pointer to a buffer that the search result will be copied to
2229- * @return 0 on success
2230- */
2231-static char *pisa_cert_get_part(char *cert, const char *name, char *r)
2232-{
2233- int level = 0, len = 0;
2234- char *p = cert, *start = NULL;
2235-
2236- if (!r) {
2237- return NULL;
2238- }
2239-
2240- if (!cert) {
2241- goto out_err;
2242- }
2243-
2244- if (!name) {
2245- goto out_err;
2246- }
2247-
2248- len = strlen(name);
2249- if (len == 0) {
2250- goto out_err;
2251- }
2252-
2253- while (*p) {
2254- if (*p == '(') {
2255- level++;
2256- if (level == 2 && !strncmp(p + 1, name, len)) {
2257- if (*(p + len + 1) == ' ') {
2258- start = p++;
2259- break;
2260- }
2261- }
2262- }
2263- if (*p == ')') {
2264- level--;
2265- }
2266- if (level == 0) {
2267- break;
2268- }
2269- p++;
2270- }
2271-
2272- if (!start) {
2273- goto out_err;
2274- }
2275-
2276- len = 0;
2277-
2278- while (*p) {
2279- if (*p == '(') {
2280- level++;
2281- }
2282- if (*p == ')') {
2283- level--;
2284- if (level == 1) {
2285- len = p - start + 1;
2286- break;
2287- }
2288- }
2289- if (level == 0) {
2290- break;
2291- }
2292- p++;
2293- }
2294-
2295- strncpy(r, start, len);
2296- r[len] = '\0';
2297-
2298- return r;
2299-
2300-out_err:
2301- r[0] = '\0';
2302- return NULL;
2303-}
2304-
2305-/**
2306- * Get the content from a SPKI certificate part.
2307- *
2308- * @param cert pointer to the certificate text or part of a certificate text
2309- * @param name pointer to the pattern we are looking for
2310- * @param r pointer to a buffer that the search result will be copied to
2311- * @return 0 on success
2312- */
2313-static void pisa_cert_get_content(char *cert, const char *name, char *r)
2314-{
2315- char *start = cert;
2316- int len = 0;
2317-
2318- if (!r) {
2319- return;
2320- }
2321-
2322- if (!cert || !name || !*name == '(') {
2323- goto out_err;
2324- }
2325-
2326- if (strlen(name) + 3 > strlen(cert)) {
2327- goto out_err;
2328- }
2329-
2330- if (strncmp(name, cert + 1, strlen(name))) {
2331- goto out_err;
2332- }
2333- start = cert + strlen(name) + 2;
2334-
2335- if (*start == '\0') {
2336- goto out_err;
2337- }
2338-
2339- len = strlen(start) - 1;
2340- if (*(start + len) != ')') {
2341- goto out_err;
2342- }
2343- strncpy(r, start, len);
2344-
2345-out_err:
2346- r[len] = '\0';
2347-}
2348-
2349-/**
2350- * Splits a certificate into semantic chunks and converts these to
2351- * sensible binary representations.
2352- *
2353- * @param cert the original certificate
2354- * @param pc internal representation of the certificate
2355- */
2356-void pisa_split_cert(char *cert, struct pisa_cert *pc)
2357-{
2358- struct tm t;
2359- char buffer1[224], buffer2[224];
2360- struct in6_addr addr;
2361-
2362- pisa_cert_get_part(cert, "not-before", buffer1);
2363- pisa_cert_get_content(buffer1, "not-before", buffer2);
2364- strptime(buffer2, "\"%Y-%m-%d_%H:%M:%S\"", &t);
2365- pc->not_before = mktime(&t);
2366-
2367- pisa_cert_get_part(cert, "not-after", buffer1);
2368- pisa_cert_get_content(buffer1, "not-after", buffer2);
2369- strptime(buffer2, "\"%Y-%m-%d_%H:%M:%S\"", &t);
2370- pc->not_after = mktime(&t);
2371-
2372- pisa_cert_get_part(cert, "issuer", buffer1);
2373- pisa_cert_get_part(buffer1, "hash hit", buffer2);
2374- pisa_cert_get_content(buffer2, "hash hit", buffer1);
2375- inet_pton(AF_INET6, buffer1, &addr);
2376- memcpy(&pc->hit_issuer, &addr, sizeof(struct in6_addr));
2377-
2378- pisa_cert_get_part(cert, "subject", buffer1);
2379- pisa_cert_get_part(buffer1, "hash hit", buffer2);
2380- pisa_cert_get_content(buffer2, "hash hit", buffer1);
2381- inet_pton(AF_INET6, buffer1, &addr);
2382- memcpy(&pc->hit_subject, &addr, sizeof(struct in6_addr));
2383-}
2384
2385=== removed file 'hipfw/pisa_cert.h'
2386--- hipfw/pisa_cert.h 2011-11-25 13:52:20 +0000
2387+++ hipfw/pisa_cert.h 1970-01-01 00:00:00 +0000
2388@@ -1,47 +0,0 @@
2389-/*
2390- * Copyright (c) 2010 Aalto University and RWTH Aachen University.
2391- *
2392- * Permission is hereby granted, free of charge, to any person
2393- * obtaining a copy of this software and associated documentation
2394- * files (the "Software"), to deal in the Software without
2395- * restriction, including without limitation the rights to use,
2396- * copy, modify, merge, publish, distribute, sublicense, and/or sell
2397- * copies of the Software, and to permit persons to whom the
2398- * Software is furnished to do so, subject to the following
2399- * conditions:
2400- *
2401- * The above copyright notice and this permission notice shall be
2402- * included in all copies or substantial portions of the Software.
2403- *
2404- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
2405- * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
2406- * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
2407- * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
2408- * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
2409- * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
2410- * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
2411- * OTHER DEALINGS IN THE SOFTWARE.
2412- */
2413-
2414-#ifndef HIPL_HIPFW_PISA_CERT_H
2415-#define HIPL_HIPFW_PISA_CERT_H
2416-
2417-#include <time.h>
2418-#include <netinet/in.h>
2419-
2420-struct pisa_cert {
2421- struct in6_addr hit_issuer;
2422- struct in6_addr hit_subject;
2423- time_t not_before;
2424- time_t not_after;
2425-};
2426-
2427-/**
2428- * Split the hip_cert_spki_info.cert part into small chunks
2429- *
2430- * @param cert the hip_cert_spki_info.cert part of the certificate
2431- * @param pc datastructure that will contain the chunks
2432- */
2433-void pisa_split_cert(char *cert, struct pisa_cert *pc);
2434-
2435-#endif /* HIPL_HIPFW_PISA_CERT_H */
2436
2437=== modified file 'lib/core/builder.c'
2438--- lib/core/builder.c 2012-01-10 17:53:47 +0000
2439+++ lib/core/builder.c 2012-02-20 21:55:24 +0000
2440@@ -3326,107 +3326,6 @@
2441 }
2442
2443 /**
2444- * Build and append a SPKI infor parameter into a HIP control message (on-the-wire)
2445- *
2446- * @param msg a pointer to the message where the parameter will be
2447- * appended
2448- * @param cert_info certificate information
2449- * @return zero on success, or negative on failure
2450- * @see <a href="http://tools.ietf.org/html/draft-ietf-hip-cert">draft-ietf-hip-cert</a>
2451- *
2452- */
2453-int hip_build_param_cert_spki_info(struct hip_common *msg,
2454- struct hip_cert_spki_info *cert_info)
2455-{
2456- struct hip_cert_spki_info local;
2457-
2458- memcpy(&local, cert_info, sizeof(struct hip_cert_spki_info));
2459- hip_set_param_type((struct hip_tlv_common *) &local,
2460- HIP_PARAM_CERT_SPKI_INFO);
2461- hip_calc_param_len((struct hip_tlv_common *) &local,
2462- sizeof(struct hip_cert_spki_info)
2463- - sizeof(struct hip_tlv_common));
2464-
2465- return hip_build_param(msg, &local);
2466-}
2467-
2468-/**
2469- * Build and append a X509 certiticate request parameter into a HIP control
2470- * message (on-the-wire)
2471- *
2472- * @param msg a pointer to the message where the parameter will be
2473- * appended
2474- * @param addr the subject for the certificate
2475- * @return zero on success, or negative on failure
2476- * @see <a href="http://tools.ietf.org/html/draft-ietf-hip-cert">draft-ietf-hip-cert</a>
2477- *
2478- */
2479-int hip_build_param_cert_x509_req(struct hip_common *msg, struct in6_addr *addr)
2480-{
2481- struct hip_cert_x509_req subj;
2482-
2483- hip_set_param_type((struct hip_tlv_common *) &subj, HIP_PARAM_CERT_X509_REQ);
2484- hip_calc_param_len((struct hip_tlv_common *) &subj,
2485- sizeof(struct hip_cert_x509_req)
2486- - sizeof(struct hip_tlv_common));
2487- ipv6_addr_copy(&subj.addr, addr);
2488-
2489- return hip_build_param(msg, &subj);
2490-}
2491-
2492-/**
2493- * build and append a X509 certificate verification parameter into a
2494- * HIP control message (on-the-wire)
2495- *
2496- * @param msg a pointer to the message where the parameter will be
2497- * appended
2498- * @param der der field
2499- * @param len length of the der field in bytes
2500- * @return zero on success, or negative on failure
2501- * @see <a href="http://tools.ietf.org/html/draft-ietf-hip-cert">draft-ietf-hip-cert</a>
2502- *
2503- */
2504-int hip_build_param_cert_x509_ver(struct hip_common *msg, char *der, int len)
2505-{
2506- struct hip_cert_x509_resp subj;
2507-
2508- hip_set_param_type((struct hip_tlv_common *) &subj, HIP_PARAM_CERT_X509_REQ);
2509- hip_calc_param_len((struct hip_tlv_common *) &subj,
2510- sizeof(struct hip_cert_x509_resp)
2511- - sizeof(struct hip_tlv_common));
2512- memcpy(&subj.der, der, len);
2513- subj.der_len = len;
2514-
2515- return hip_build_param(msg, &subj);
2516-}
2517-
2518-/**
2519- * build and append a X509 certificate response into a HIP control message
2520- * (on-the-wire)
2521- *
2522- * @param msg a pointer to the message where the parameter will be
2523- * appended
2524- * @param der der field
2525- * @param len length of the der field in bytes
2526- * @return zero on success, or negative on failure
2527- * @see <a href="http://tools.ietf.org/html/draft-ietf-hip-cert">draft-ietf-hip-cert</a>
2528- *
2529- */
2530-int hip_build_param_cert_x509_resp(struct hip_common *msg, char *der, int len)
2531-{
2532- struct hip_cert_x509_resp local;
2533- hip_set_param_type((struct hip_tlv_common *) &local,
2534- HIP_PARAM_CERT_X509_RESP);
2535- hip_calc_param_len((struct hip_tlv_common *) &local,
2536- sizeof(struct hip_cert_x509_resp)
2537- - sizeof(struct hip_tlv_common));
2538- memcpy(&local.der, der, len);
2539- local.der_len = len;
2540-
2541- return hip_build_param(msg, &local);
2542-}
2543-
2544-/**
2545 * Build an append a zone parameter for hit-to-ip extension.
2546 *
2547 * @param msg a pointer to the message where the parameter will be
2548
2549=== modified file 'lib/core/builder.h'
2550--- lib/core/builder.h 2011-04-04 11:46:20 +0000
2551+++ lib/core/builder.h 2012-02-20 21:55:24 +0000
2552@@ -36,7 +36,6 @@
2553 #include <openssl/ec.h>
2554 #endif /* HAVE_EC_CRYPTO */
2555
2556-#include "certtools.h"
2557 #include "debug.h"
2558 #include "icomm.h"
2559 #include "state.h"
2560@@ -156,11 +155,6 @@
2561 const in_port_t port);
2562 int hip_build_param_via_rvs(struct hip_common *msg,
2563 const struct in6_addr rvs_addresses[]);
2564-int hip_build_param_cert_spki_info(struct hip_common *msg,
2565- struct hip_cert_spki_info *cert_info);
2566-int hip_build_param_cert_x509_req(struct hip_common *, struct in6_addr *);
2567-int hip_build_param_cert_x509_resp(struct hip_common *, char *, int);
2568-int hip_build_param_cert_x509_ver(struct hip_common *, char *, int);
2569
2570 int hip_build_param_hit_to_ip_set(struct hip_common *, const char *);
2571 int hip_build_user_hdr(struct hip_common *, hip_hdr, hip_hdr_err);
2572
2573=== removed file 'lib/core/certtools.c'
2574--- lib/core/certtools.c 2012-01-14 15:29:47 +0000
2575+++ lib/core/certtools.c 1970-01-01 00:00:00 +0000
2576@@ -1,856 +0,0 @@
2577-/*
2578- * Copyright (c) 2010 Aalto University and RWTH Aachen University.
2579- *
2580- * Permission is hereby granted, free of charge, to any person
2581- * obtaining a copy of this software and associated documentation
2582- * files (the "Software"), to deal in the Software without
2583- * restriction, including without limitation the rights to use,
2584- * copy, modify, merge, publish, distribute, sublicense, and/or sell
2585- * copies of the Software, and to permit persons to whom the
2586- * Software is furnished to do so, subject to the following
2587- * conditions:
2588- *
2589- * The above copyright notice and this permission notice shall be
2590- * included in all copies or substantial portions of the Software.
2591- *
2592- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
2593- * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
2594- * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
2595- * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
2596- * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
2597- * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
2598- * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
2599- * OTHER DEALINGS IN THE SOFTWARE.
2600- */
2601-
2602-/**
2603- * @file
2604- * certificate building and verification functions to use with HIP
2605- */
2606-
2607-#include <regex.h>
2608-#include <stdio.h>
2609-#include <stdlib.h>
2610-#include <string.h>
2611-#include <openssl/bn.h>
2612-#include <openssl/conf.h>
2613-#include <openssl/dsa.h>
2614-#include <openssl/err.h>
2615-#include <openssl/evp.h>
2616-#include <openssl/rsa.h>
2617-#include <openssl/safestack.h>
2618-
2619-#include "crypto.h"
2620-#include "debug.h"
2621-#include "ife.h"
2622-#include "message.h"
2623-#include "prefix.h"
2624-#include "straddr.h"
2625-#include "certtools.h"
2626-
2627-/*******************************************************************************
2628- * FUNCTIONS FOR SPKI *
2629- *******************************************************************************/
2630-
2631-/**
2632- * Function that verifies the signature in
2633- * the given SPKI cert sent by the "client"
2634- *
2635- * @param cert points to hip_cert_spki_info that is going to be verified
2636- *
2637- * @return 0 if signature matches, -1 if error or signature did NOT match
2638- *
2639- * @note see hip_cert_spki_char2certinfo to convert from wire to hip_cert_spki_info
2640- */
2641-int hip_cert_spki_lib_verify(struct hip_cert_spki_info *cert)
2642-{
2643- int err = 0, start = 0, stop = 0, evpret = 0, keylen = 0, algo = 0;
2644- char buf[200];
2645-
2646- unsigned char sha_digest[21];
2647- unsigned char *sha_retval;
2648- unsigned char *signature_hash = NULL;
2649- unsigned char *signature_hash_b64 = NULL;
2650- unsigned char *signature_b64 = NULL;
2651-
2652- unsigned char *signature = NULL;
2653-
2654- /** RSA */
2655- RSA *rsa = NULL;
2656- unsigned long e_code;
2657- char *e_hex = NULL;
2658- unsigned char *modulus_b64 = NULL;
2659- unsigned char *modulus = NULL;
2660-
2661- /** DSA */
2662- DSA *dsa = NULL;
2663- unsigned char *p_bin = NULL, *q_bin = NULL, *g_bin = NULL, *y_bin = NULL;
2664- unsigned char *p_b64 = NULL, *q_b64 = NULL, *g_b64 = NULL, *y_b64 = NULL;
2665- DSA_SIG *dsa_sig;
2666-
2667- /* rules for regular expressions */
2668-
2669- /*
2670- * Rule to get the info if we are using DSA
2671- */
2672- char dsa_rule[] = "[d][s][a][-][p][k][c][s][1][-][s][h][a][1]";
2673-
2674- /*
2675- * Rule to get the info if we are using RSA
2676- */
2677- char rsa_rule[] = "[r][s][a][-][p][k][c][s][1][-][s][h][a][1]";
2678-
2679- /*
2680- * Rule to get DSA p
2681- * Look for pattern "(p |" and stop when first "|"
2682- * anything in base 64 is accepted inbetween
2683- */
2684- char p_rule[] = "[(][p][ ][|][[A-Za-z0-9+/()#=-]*[|]";
2685-
2686- /*
2687- * Rule to get DSA q
2688- * Look for pattern "(q |" and stop when first "|"
2689- * anything in base 64 is accepted inbetween
2690- */
2691- char q_rule[] = "[(][q][ ][|][[A-Za-z0-9+/()#=-]*[|]";
2692-
2693- /*
2694- * Rule to get DSA g
2695- * Look for pattern "(g |" and stop when first "|"
2696- * anything in base 64 is accepted inbetween
2697- */
2698- char g_rule[] = "[(][g][ ][|][[A-Za-z0-9+/()#=-]*[|]";
2699-
2700- /*
2701- * Rule to get DSA y / pub_key
2702- * Look for pattern "(y |" and stop when first "|"
2703- * anything in base 64 is accepted inbetween
2704- */
2705- char y_rule[] = "[(][y][ ][|][[A-Za-z0-9+/()#=-]*[|]";
2706-
2707- /*
2708- * rule to get the public exponent RSA
2709- * Look for the part that says # and after that some hex blob and #
2710- */
2711- char e_rule[] = "[#][0-9A-Fa-f]*[#]";
2712-
2713- /*
2714- * rule to get the public modulus RSA
2715- * Look for the part that starts with '|' and after that anything
2716- * that is in base 64 char set and then '|' again
2717- */
2718- char n_rule[] = "[|][A-Za-z0-9+/()#=-]*[|]";
2719-
2720- /*
2721- * rule to get the signature hash
2722- * Look for the similar than the n_rule
2723- */
2724- char h_rule[] = "[|][A-Za-z0-9+/()#=-]*[|]";
2725-
2726- /*
2727- * rule to get the signature
2728- * Look for part that starts ")|" and base 64 blob after it
2729- * and stops to '|' char remember to add and subtract 2 from
2730- * the indexes below
2731- */
2732- char s_rule[] = "[)][|][A-Za-z0-9+/()#=-]*[|]";
2733-
2734- /* check the algo DSA or RSA */
2735- HIP_DEBUG("Verifying\nRunning regexps to identify algo\n");
2736- start = stop = 0;
2737- algo = hip_cert_regex(dsa_rule, cert->public_key, &start, &stop);
2738- if (algo != -1) {
2739- HIP_DEBUG("Public-key is DSA\n");
2740- algo = HIP_HI_DSA;
2741- goto algo_check_done;
2742- }
2743- start = stop = 0;
2744- algo = hip_cert_regex(rsa_rule, cert->public_key, &start, &stop);
2745- if (algo != -1) {
2746- HIP_DEBUG("Public-key is RSA\n");
2747- algo = HIP_HI_RSA;
2748- goto algo_check_done;
2749- }
2750- HIP_DEBUG((1 != 1), -1, "Unknown algorithm\n");
2751-
2752-algo_check_done:
2753- if (algo == HIP_HI_RSA) {
2754- /* malloc space for new rsa */
2755- rsa = RSA_new();
2756- HIP_IFEL(!rsa, -1, "Failed to malloc RSA\n");
2757-
2758- /* extract the public-key from cert to rsa */
2759-
2760- /* public exponent first */
2761- start = stop = 0;
2762- HIP_IFEL(hip_cert_regex(e_rule, cert->public_key, &start, &stop), -1,
2763- "Failed to run hip_cert_regex (exponent)\n");
2764- e_hex = malloc(stop - start);
2765- HIP_IFEL(!e_hex, -1, "Malloc for e_hex failed\n");
2766- snprintf((char *) e_hex, stop - start - 1, "%s",
2767- &cert->public_key[start + 1]);
2768-
2769- /* public modulus */
2770- start = stop = 0;
2771- HIP_IFEL(hip_cert_regex(n_rule, cert->public_key, &start, &stop), -1,
2772- "Failed to run hip_cert_regex (modulus)\n");
2773- modulus_b64 = calloc(1, stop - start + 1);
2774- HIP_IFEL(!modulus_b64, -1, "calloc for modulus_b64 failed\n");
2775- modulus = calloc(1, stop - start + 1);
2776- HIP_IFEL(!modulus, -1, "calloc for modulus failed\n");
2777- snprintf((char *) modulus_b64, stop - start - 1, "%s",
2778- &cert->public_key[start + 1]);
2779-
2780- /* put the stuff into the RSA struct */
2781- BN_hex2bn(&rsa->e, e_hex);
2782- evpret = EVP_DecodeBlock(modulus, modulus_b64,
2783- strlen((char *) modulus_b64));
2784-
2785- /* EVP returns a multiple of 3 octets, subtract any extra */
2786- keylen = evpret;
2787- if (keylen % 4 != 0) {
2788- --keylen;
2789- keylen = keylen - keylen % 2;
2790- }
2791- signature = malloc(keylen);
2792- HIP_IFEL(!signature, -1, "Malloc for signature failed.\n");
2793- rsa->n = BN_bin2bn(modulus, keylen, 0);
2794- } else if (algo == HIP_HI_DSA) {
2795- /* malloc space for new dsa */
2796- dsa = DSA_new();
2797- HIP_IFEL(!dsa, -1, "Failed to malloc DSA\n");
2798-
2799- /* Extract public key from the cert */
2800-
2801- /* dsa->p */
2802- start = stop = 0;
2803- HIP_IFEL(hip_cert_regex(p_rule, cert->public_key, &start, &stop), -1,
2804- "Failed to run hip_cert_regex dsa->p\n");
2805- p_b64 = calloc(1, stop - start + 1);
2806- HIP_IFEL(!p_b64, -1, "calloc for p_b64 failed\n");
2807- p_bin = calloc(1, stop - start + 1);
2808- HIP_IFEL(!p_bin, -1, "calloc for p_bin failed\n");
2809- snprintf((char *) p_b64, stop - start - 1, "%s",
2810- &cert->public_key[start + 1]);
2811- evpret = EVP_DecodeBlock(p_bin, p_b64, strlen((char *) p_b64));
2812-
2813- /* dsa->q */
2814- start = stop = 0;
2815- HIP_IFEL(hip_cert_regex(q_rule, cert->public_key, &start, &stop), -1,
2816- "Failed to run hip_cert_regex dsa->q\n");
2817- q_b64 = calloc(1, stop - start + 1);
2818- HIP_IFEL(!q_b64, -1, "calloc for q_b64 failed\n");
2819- q_bin = calloc(1, stop - start + 1);
2820- HIP_IFEL(!q_bin, -1, "calloc for q_bin failed\n");
2821- snprintf((char *) q_b64, stop - start - 1, "%s",
2822- &cert->public_key[start + 1]);
2823- evpret = EVP_DecodeBlock(q_bin, q_b64, strlen((char *) q_b64));
2824-
2825- /* dsa->g */
2826- start = stop = 0;
2827- HIP_IFEL(hip_cert_regex(g_rule, cert->public_key, &start, &stop), -1,
2828- "Failed to run hip_cert_regex dsa->g\n");
2829- g_b64 = calloc(1, stop - start + 1);
2830- HIP_IFEL(!g_b64, -1, "calloc for g_b64 failed\n");
2831- g_bin = calloc(1, stop - start + 1);
2832- HIP_IFEL(!g_bin, -1, "calloc for g_bin failed\n");
2833- snprintf((char *) g_b64, stop - start - 1, "%s",
2834- &cert->public_key[start + 1]);
2835- evpret = EVP_DecodeBlock(g_bin, g_b64, strlen((char *) g_b64));
2836-
2837- /* dsa->y */
2838- start = stop = 0;
2839- HIP_IFEL(hip_cert_regex(y_rule, cert->public_key, &start, &stop), -1,
2840- "Failed to run hip_cert_regex dsa->y\n");
2841- y_b64 = calloc(1, stop - start + 1);
2842- HIP_IFEL(!y_b64, -1, "calloc for y_b64 failed\n");
2843- y_bin = calloc(1, stop - start + 1);
2844- HIP_IFEL(!y_bin, -1, "calloc for y_bin failed\n");
2845- snprintf((char *) y_b64, stop - start - 1, "%s",
2846- &cert->public_key[start + 1]);
2847- evpret = EVP_DecodeBlock(y_bin, y_b64, strlen((char *) y_b64));
2848- } else if (algo == HIP_HI_ECDSA) {
2849- HIP_OUT_ERR(-1, "Call to unimplemented ECDSA case.\n");
2850- } else {
2851- HIP_OUT_ERR(-1, "Unknown algorithm\n");
2852- }
2853-
2854- /* build sha1 digest that will be signed */
2855- HIP_IFEL(!(sha_retval = SHA1((unsigned char *) cert->cert,
2856- strlen((char *) cert->cert), sha_digest)),
2857- -1, "SHA1 error when creating digest.\n");
2858-
2859- /* Get the signature hash and compare it to the sha_digest we just made */
2860- start = stop = 0;
2861- HIP_IFEL(hip_cert_regex(h_rule, cert->signature, &start, &stop), -1,
2862- "Failed to run hip_cert_regex (signature hash)\n");
2863- signature_hash_b64 = calloc(1, stop - start + 1);
2864- HIP_IFEL(!signature_hash_b64, -1, "Failed to calloc signature_hash_b64\n");
2865- signature_hash = malloc(stop - start + 1);
2866- HIP_IFEL(!signature_hash, -1, "Failed to malloc signature_hash\n");
2867- snprintf((char *) signature_hash_b64, stop - start - 1, "%s",
2868- &cert->signature[start + 1]);
2869- evpret = EVP_DecodeBlock(signature_hash, signature_hash_b64,
2870- strlen((char *) signature_hash_b64));
2871- HIP_IFEL(memcmp(sha_digest, signature_hash, 20), -1,
2872- "Signature hash did not match of the one made from the"
2873- "cert sequence in the certificate\n");
2874-
2875- /* memset signature and put it into its place */
2876- start = stop = 0;
2877- HIP_IFEL(hip_cert_regex(s_rule, cert->signature, &start, &stop), -1,
2878- "Failed to run hip_cert_regex (signature)\n");
2879- signature_b64 = calloc(1, stop - start + 1);
2880- HIP_IFEL(!signature_b64, -1, "Failed to calloc signature_b64\n");
2881- snprintf((char *) signature_b64, stop - start - 2, "%s",
2882- &cert->signature[start + 2]);
2883- if (algo == HIP_HI_DSA) {
2884- signature = malloc(stop - start + 1);
2885- HIP_IFEL(!signature, -1, "Failed to malloc signature (dsa)\n");
2886- }
2887- evpret = EVP_DecodeBlock(signature, signature_b64,
2888- strlen((char *) signature_b64));
2889-
2890- if (algo == HIP_HI_RSA) {
2891- /* do the verification */
2892- err = RSA_verify(NID_sha1, sha_digest, SHA_DIGEST_LENGTH,
2893- signature, RSA_size(rsa), rsa);
2894- e_code = ERR_get_error();
2895- ERR_load_crypto_strings();
2896- ERR_error_string(e_code, buf);
2897-
2898- /* RSA_verify returns 1 if success. */
2899- cert->success = err == 1 ? 0 : -1;
2900- HIP_IFEL((err = err == 1 ? 0 : -1), -1, "RSA_verify error\n");
2901- } else if (algo == HIP_HI_DSA) {
2902- /* build the signature structure */
2903- dsa_sig = DSA_SIG_new();
2904- HIP_IFEL(!dsa_sig, 1, "Failed to allocate DSA_SIG\n");
2905- dsa_sig->r = BN_bin2bn(&signature[1], DSA_PRIV, NULL);
2906- dsa_sig->s = BN_bin2bn(&signature[1 + DSA_PRIV], DSA_PRIV, NULL);
2907-
2908- /* verify the DSA signature */
2909- err = DSA_do_verify(sha_digest, SHA_DIGEST_LENGTH,
2910- dsa_sig, dsa) == 0 ? 1 : 0;
2911-
2912- /* DSA_do_verify returns 1 if success. */
2913- cert->success = err == 1 ? 0 : -1;
2914- HIP_IFEL((err = err == 1 ? 0 : -1), -1, "DSA_do_verify error\n");
2915- } else if (algo == HIP_HI_ECDSA) {
2916- HIP_OUT_ERR(-1, "Call to unimplemented ECDSA case.\n");
2917- } else {
2918- HIP_OUT_ERR(-1, "Unknown algorithm\n");
2919- }
2920-
2921-out_err:
2922- free(signature_hash_b64);
2923- free(signature_hash);
2924- free(modulus_b64);
2925- free(modulus);
2926- free(e_hex);
2927- RSA_free(rsa);
2928- DSA_free(dsa);
2929- return err;
2930-}
2931-
2932-/**
2933- * Function to build the basic cert object of SPKI clears public-key
2934- * object and signature in hip_cert_spki_header
2935- *
2936- * @param minimal_content holds the struct hip_cert_spki_header
2937- * containing the minimal needed information for
2938- * cert object, also contains the char table where
2939- * the cert object is to be stored
2940- *
2941- * @return always 0
2942- */
2943-static int cert_spki_build_cert(struct hip_cert_spki_info *minimal_content)
2944-{
2945- char needed[] = "(cert )";
2946- memset(minimal_content->public_key, '\0', sizeof(minimal_content->public_key));
2947- memset(minimal_content->cert, '\0', sizeof(minimal_content->cert));
2948- memset(minimal_content->signature, '\0', sizeof(minimal_content->signature));
2949- sprintf(minimal_content->cert, "%s", needed);
2950-
2951- return 0;
2952-}
2953-
2954-/**
2955- * Function for injecting objects to cert object
2956- *
2957- * @param to hip_cert_spki_info containing the char table where to insert
2958- * @param after is a char pointer for the regcomp after which the inject happens
2959- * @param what is char pointer of what to
2960- *
2961- * @return 0 if ok and negative if error. -1 returned for example when after is NOT found
2962- */
2963-static int cert_spki_inject(struct hip_cert_spki_info *to,
2964- const char *after, const char *what)
2965-{
2966- int err = 0, status = 0;
2967- regex_t re;
2968- regmatch_t pm[1];
2969- char *tmp_cert;
2970-
2971- tmp_cert = calloc(1, strlen(to->cert) + strlen(what) + 1);
2972- if (!tmp_cert) {
2973- return -ENOMEM;
2974- }
2975- /* Compiling the regular expression */
2976- HIP_IFEL(regcomp(&re, after, REG_EXTENDED), -1,
2977- "Compilation of the regular expression failed\n");
2978- /* Running the regular expression */
2979- HIP_IFEL((status = regexec(&re, to->cert, 1, pm, 0)), -1,
2980- "Handling of regular expression failed\n");
2981- /* Using tmp char table to do the inject (remember the terminators)
2982- * first the beginning */
2983- snprintf(tmp_cert, pm[0].rm_eo + 2, "%s", to->cert);
2984- /* Then the middle part to be injected */
2985- snprintf(&tmp_cert[pm[0].rm_eo + 1], strlen(what) + 1, "%s", what);
2986- /* then glue back the rest of the original at the end */
2987- snprintf(&tmp_cert[(pm[0].rm_eo + strlen(what) + 1)],
2988- (strlen(to->cert) - pm[0].rm_eo), "%s", &to->cert[pm[0].rm_eo + 1]);
2989- /* move tmp to the result */
2990- sprintf(to->cert, "%s", tmp_cert);
2991-out_err:
2992- free(tmp_cert);
2993- regfree(&re);
2994- return err;
2995-}
2996-
2997-/**
2998- * Function to build the create minimal SPKI cert (plus socket parameter)
2999- *
3000- * @param content holds the struct hip_cert_spki_info containing
3001- * the minimal needed information for cert object,
3002- * also contains the char table where the cert object
3003- * is to be stored
3004- * @param issuer_type With HIP its HIT
3005- * @param issuer HIT in representation encoding 2001:001...
3006- * @param subject_type With HIP its HIT
3007- * @param subject HIT in representation encoding 2001:001...
3008- * @param not_before time in timeval before which the cert should not be used
3009- * @param not_after time in timeval after which the cert should not be used
3010- * @param hip_user_socket socket, already connected to hipd, to pass through to
3011- * hip_send_recv_daemon_info
3012- * @return 0 if ok -1 if error
3013- */
3014-static int cert_spki_create_cert_sock(struct hip_cert_spki_info *content,
3015- const char *issuer_type,
3016- struct in6_addr *issuer,
3017- const char *subject_type,
3018- struct in6_addr *subject,
3019- time_t *not_before,
3020- time_t *not_after,
3021- int hip_user_socket)
3022-{
3023- int err = 0;
3024- char *tmp_issuer = NULL;
3025- char *tmp_subject = NULL;
3026- char *tmp_before = NULL;
3027- char *tmp_after = NULL;
3028- struct tm *ts = NULL;
3029- char buf_before[80];
3030- char buf_after[80];
3031- char present_issuer[41] = { 0 };
3032- char present_subject[41] = { 0 };
3033- struct hip_common *msg = NULL;
3034- const struct hip_cert_spki_info *returned = NULL;
3035-
3036- /* Malloc needed */
3037- tmp_issuer = calloc(1, 128);
3038- if (!tmp_issuer) {
3039- goto out_err; /* Why does this return 0? */
3040- }
3041- tmp_subject = calloc(1, 128);
3042- if (!tmp_subject) {
3043- goto out_err;
3044- }
3045- tmp_before = calloc(1, 128);
3046- if (!tmp_before) {
3047- goto out_err;
3048- }
3049- tmp_after = calloc(1, 128);
3050- if (!tmp_after) {
3051- goto out_err;
3052- }
3053- HIP_IFEL(!(msg = malloc(HIP_MAX_PACKET)), -1,
3054- "Malloc for msg failed\n");
3055-
3056- /* Make needed transforms to the date */
3057- /* Format and print the time, "yyyy-mm-dd hh:mm:ss"
3058- * (not-after "1998-04-15_00:00:00") */
3059- ts = localtime(not_before);
3060- strftime(buf_before, sizeof(buf_before), "%Y-%m-%d_%H:%M:%S", ts);
3061- ts = localtime(not_after);
3062- strftime(buf_after, sizeof(buf_after), "%Y-%m-%d_%H:%M:%S", ts);
3063-
3064- sprintf(tmp_before, "(not-before \"%s\")", buf_before);
3065- sprintf(tmp_after, "(not-after \"%s\")", buf_after);
3066-
3067- ipv6_addr_copy(&content->issuer_hit, issuer);
3068- inet_ntop(AF_INET6, issuer, present_issuer, INET6_ADDRSTRLEN);
3069- inet_ntop(AF_INET6, subject, present_subject, INET6_ADDRSTRLEN);
3070-
3071- sprintf(tmp_issuer, "(hash %s %s)", issuer_type, present_issuer);
3072- sprintf(tmp_subject, "(hash %s %s)", subject_type, present_subject);
3073-
3074- /* Create the cert sequence */
3075- HIP_IFEL(cert_spki_build_cert(content), -1,
3076- "cert_spki_build_cert failed\n");
3077-
3078- HIP_IFEL(cert_spki_inject(content, "cert", tmp_after), -1,
3079- "cert_spki_inject failed to inject\n");
3080- HIP_IFEL(cert_spki_inject(content, "cert", tmp_before), -1,
3081- "cert_spki_inject failed to inject\n");
3082- HIP_IFEL(cert_spki_inject(content, "cert", "(subject )"), -1,
3083- "cert_spki_inject failed to inject\n");
3084- HIP_IFEL(cert_spki_inject(content, "subject", tmp_subject), -1,
3085- "cert_spki_inject failed to inject\n");
3086- HIP_IFEL(cert_spki_inject(content, "cert", "(issuer )"), -1,
3087- "cert_spki_inject failed to inject\n");
3088- HIP_IFEL(cert_spki_inject(content, "issuer", tmp_issuer), -1,
3089- "cert_spki_inject failed to inject\n");
3090-
3091- /* Create the signature and the public-key sequences */
3092-
3093- /* Send the daemon the struct hip_cert_spki_header
3094- * containing the cert sequence in content->cert.
3095- * As a result you should get the struct back with
3096- * public-key and signature fields filled */
3097-
3098- /* build the msg to be sent to the daemon */
3099- hip_msg_init(msg);
3100- HIP_IFEL(hip_build_user_hdr(msg, HIP_MSG_CERT_SPKI_SIGN, 0), -1,
3101- "Failed to build user header\n");
3102- HIP_IFEL(hip_build_param_cert_spki_info(msg, content), -1,
3103- "Failed to build cert_info\n");
3104- /* send and wait */
3105- HIP_DEBUG("Sending request to sign SPKI cert sequence to "
3106- "daemon and waiting for answer\n");
3107- hip_send_recv_daemon_info(msg, 0, hip_user_socket);
3108-
3109- /* get the struct from the message sent back by the daemon */
3110- HIP_IFEL(!(returned = hip_get_param(msg, HIP_PARAM_CERT_SPKI_INFO)),
3111- -1, "No hip_cert_spki_info struct found from daemons msg\n");
3112-
3113- memcpy(content, returned, sizeof(struct hip_cert_spki_info));
3114-
3115-out_err:
3116- /* free everything malloced */
3117- free(tmp_before);
3118- free(tmp_after);
3119- free(tmp_issuer);
3120- free(tmp_subject);
3121- free(msg);
3122- return err;
3123-}
3124-
3125-/**
3126- * Function to build the create minimal SPKI cert
3127- *
3128- * @param content holds the struct hip_cert_spki_info containing
3129- * the minimal needed information for cert object,
3130- * also contains the char table where the cert object
3131- * is to be stored
3132- * @param issuer_type With HIP its HIT
3133- * @param issuer HIT in representation encoding 2001:001...
3134- * @param subject_type With HIP its HIT
3135- * @param subject HIT in representation encoding 2001:001...
3136- * @param not_before time in timeval before which the cert should not be used
3137- * @param not_after time in timeval after which the cert should not be used
3138- * @return 0 if ok -1 if error
3139- */
3140-int hip_cert_spki_create_cert(struct hip_cert_spki_info *content,
3141- const char *issuer_type, struct in6_addr *issuer,
3142- const char *subject_type, struct in6_addr *subject,
3143- time_t *not_before, time_t *not_after)
3144-{
3145- return cert_spki_create_cert_sock(content, issuer_type, issuer,
3146- subject_type, subject, not_before,
3147- not_after, 0);
3148-}
3149-
3150-/**
3151- * Function that takes the cert in single char table and constructs
3152- * hip_cert_spki_info from it
3153- *
3154- * @param from char pointer to the whole certificate
3155- * @param to hip_cert_spki_info containing the char table where to insert
3156- *
3157- * @return 0 if ok and negative if error.
3158- */
3159-int hip_cert_spki_char2certinfo(char *from, struct hip_cert_spki_info *to)
3160-{
3161- int start = 0, stop = 0;
3162- /*
3163- * p_rule looks for string "(public_key " after which there can be
3164- * pretty much anything until string "|)))" is encountered.
3165- * This is the public-key sequence.
3166- */
3167- char p_rule[] = "[(]public_key [ A-Za-z0-9+|/()#=-]*[|][)][)][)]";
3168- /*
3169- * c_rule looks for string "(cert " after which there can be
3170- * pretty much anything until string '"))' is encountered.
3171- * This is the cert sequence.
3172- */
3173- char c_rule[] = "[(]cert [ A-Za-z0-9+|/():=_\"-]*[\"][)][)]"; //\" is one char
3174- /*
3175- * s_rule looks for string "(signature " after which there can be
3176- * pretty much anything until string "|))" is encountered.
3177- * This is the signature sequence.
3178- */
3179- char s_rule[] = "[(]signature [ A-Za-z0-9+/|()=]*[|][)][)]";
3180-
3181- /* Look for the public key */
3182- if (hip_cert_regex(p_rule, from, &start, &stop)) {
3183- HIP_ERROR("Failed to run hip_cert_regex (public-key)\n");
3184- return -1;
3185- }
3186- snprintf(to->public_key, stop - start + 1, "%s", &from[start]);
3187-
3188- /* Look for the cert sequence */
3189- start = stop = 0;
3190- if (hip_cert_regex(c_rule, from, &start, &stop)) {
3191- HIP_ERROR("Failed to run hip_cert_regex (cert)\n");
3192- return -1;
3193- }
3194- snprintf(to->cert, stop - start + 1, "%s", &from[start]);
3195-
3196- /* look for the signature sequence */
3197- start = stop = 0;
3198- if (hip_cert_regex(s_rule, from, &start, &stop)) {
3199- HIP_ERROR("Failed to run hip_cert_regex (signature)\n");
3200- return -1;
3201- }
3202- snprintf(to->signature, stop - start + 1, "%s", &from[start]);
3203-
3204- return 0;
3205-}
3206-
3207-/**
3208- * Function that sends the given hip_cert_spki_info to the daemon to
3209- * verification
3210- *
3211- * @param to_verification is the cert to be verified
3212- *
3213- * @return 0 if ok and negative if error or unsuccessful.
3214- *
3215- * @note use hip_cert_spki_char2certinfo to build the hip_cert_spki_info
3216- */
3217-int hip_cert_spki_send_to_verification(struct hip_cert_spki_info *to_verification)
3218-{
3219- int err = 0;
3220- struct hip_common *msg;
3221- const struct hip_cert_spki_info *returned;
3222-
3223- if (!(msg = malloc(HIP_MAX_PACKET))) {
3224- HIP_ERROR("Malloc for msg failed\n");
3225- return -ENOMEM;
3226- }
3227- hip_msg_init(msg);
3228- /* build the msg to be sent to the daemon */
3229- HIP_IFEL(hip_build_user_hdr(msg, HIP_MSG_CERT_SPKI_VERIFY, 0), -1,
3230- "Failed to build user header\n");
3231- HIP_IFEL(hip_build_param_cert_spki_info(msg, to_verification), -1,
3232- "Failed to build cert_info\n");
3233-
3234- /* send and wait */
3235- HIP_DEBUG("Sending request to verify SPKI cert to "
3236- "daemon and waiting for answer\n");
3237- hip_send_recv_daemon_info(msg, 0, 0);
3238-
3239- HIP_IFEL(!(returned = hip_get_param(msg, HIP_PARAM_CERT_SPKI_INFO)),
3240- -1, "No hip_cert_spki_info struct found from daemons msg\n");
3241-
3242- memcpy(to_verification, returned, sizeof(struct hip_cert_spki_info));
3243-
3244-out_err:
3245- free(msg);
3246- return err;
3247-}
3248-
3249-/******************************************************************************
3250- * FUNCTIONS FOR x509v3 *
3251- ******************************************************************************/
3252-
3253-/**
3254- * Function that requests for a certificate from daemon and gives it back.
3255- *
3256- * @param subject is the subjects HIT
3257- *
3258- * @param certificate is pointer to a buffer to which this function writes the completed cert
3259- *
3260- * @return positive on success negative otherwise
3261- *
3262- * @note The certificate is given in DER encoding
3263- */
3264-int hip_cert_x509v3_request_certificate(struct in6_addr *subject,
3265- unsigned char *certificate)
3266-{
3267- int err = 0;
3268- struct hip_common *msg;
3269- const struct hip_cert_x509_resp *p;
3270-
3271- if (!(msg = malloc(HIP_MAX_PACKET))) {
3272- HIP_ERROR("Malloc for msg failed\n");
3273- return -ENOMEM;
3274- }
3275- hip_msg_init(msg);
3276- /* build the msg to be sent to the daemon */
3277-
3278- HIP_IFEL(hip_build_user_hdr(msg, HIP_MSG_CERT_X509V3_SIGN, 0), -1,
3279- "Failed to build user header\n");
3280- HIP_IFEL(hip_build_param_cert_x509_req(msg, subject), -1,
3281- "Failed to build cert_info\n");
3282- /* send and wait */
3283- HIP_DEBUG("Sending request to sign x509 cert to "
3284- "daemon and waiting for answer\n");
3285- hip_send_recv_daemon_info(msg, 0, 0);
3286- /* get the struct from the message sent back by the daemon */
3287- HIP_IFEL(!(p = hip_get_param(msg, HIP_PARAM_CERT_X509_RESP)), -1,
3288- "No name x509 struct found\n");
3289- memcpy(certificate, p->der, p->der_len);
3290- err = p->der_len;
3291-
3292-out_err:
3293- free(msg);
3294- return err;
3295-}
3296-
3297-/**
3298- * Function that requests for a verification of a certificate from
3299- * daemon and tells the result.
3300- *
3301- * @param certificate is pointer to a certificate to be verified
3302- * @param len is the length of the cert in certificate parameter in bytes
3303- *
3304- * @return 0 on success negative otherwise
3305- *
3306- * @note give the certificate in PEM encoding
3307- */
3308-int hip_cert_x509v3_request_verification(unsigned char *certificate, int len)
3309-{
3310- int err = 0;
3311- struct hip_common *msg;
3312- const struct hip_cert_x509_resp *received;
3313-
3314- if (!(msg = malloc(HIP_MAX_PACKET))) {
3315- HIP_ERROR("Malloc for msg failed\n");
3316- return -ENOMEM;
3317- }
3318- hip_msg_init(msg);
3319-
3320- /* build the msg to be sent to the daemon */
3321- HIP_IFEL(hip_build_user_hdr(msg, HIP_MSG_CERT_X509V3_VERIFY, 0), -1,
3322- "Failed to build user header\n");
3323- HIP_IFEL(hip_build_param_cert_x509_ver(msg, (char *) certificate, len), -1,
3324- "Failed to build cert_info\n");
3325-
3326- /* send and wait */
3327- HIP_DEBUG("Sending request to verify x509 cert to "
3328- "daemon and waiting for answer\n");
3329- hip_send_recv_daemon_info(msg, 0, 0);
3330-
3331- /* get the struct from the message sent back by the daemon */
3332- HIP_IFEL(!(received = hip_get_param(msg, HIP_PARAM_CERT_X509_RESP)), -1,
3333- "No x509 struct found\n");
3334- err = hip_get_msg_err(msg);
3335- if (err == 0) {
3336- HIP_DEBUG("Verified successfully\n");
3337- } else {
3338- HIP_DEBUG("Verification failed\n");
3339- }
3340-
3341-out_err:
3342- free(msg);
3343- return err;
3344-}
3345-
3346-/*****************************************************************************
3347- * UTILITY FUNCTIONS *
3348- *****************************************************************************/
3349-
3350-/**
3351- * Read configuration section from loaded configuration file.
3352- *
3353- * @param section_name the name of the section to be retrieved
3354- * @param conf the loaded configuration to read from
3355- *
3356- * @return STACK_OF(CONF_VALUE) pointer if OK, NULL on error
3357- *
3358- * @note Remember to open the configuration file with hip_cert_open_conf() and
3359- * close it after processing with NCONF_free().
3360- */
3361-STACK_OF(CONF_VALUE) *hip_read_conf_section(const char *section_name,
3362- CONF *conf)
3363-{
3364- STACK_OF(CONF_VALUE) *sec;
3365-
3366- if (!(sec = NCONF_get_section(conf, section_name))) {
3367- HIP_ERROR("Section %s was not in the configuration (%s)\n",
3368- section_name, HIP_CERT_CONF_PATH);
3369- return NULL;
3370- }
3371-
3372- return sec;
3373-}
3374-
3375-/**
3376- * Load a configuration file from HIP_CERT_CONF_PATH.
3377- *
3378- * @return CONF pointer if OK, NULL on error
3379- */
3380-CONF *hip_open_conf(const char *filename)
3381-{
3382- long err;
3383- CONF *conf;
3384-
3385- conf = NCONF_new(NCONF_default());
3386- if (!NCONF_load(conf, filename, &err)) {
3387- HIP_ERROR("Error opening the configuration file");
3388- return NULL;
3389- }
3390- return conf;
3391-}
3392-
3393-/**
3394- * Function that wraps regular expression stuff and gives the answer :)
3395- *
3396- * @param what is a char pointer to the rule used in the search (POSIX)
3397- * @param from where are we looking for it char pointer
3398- * @param start will store the start point of the found substr
3399- * @param stop will store the end point of the found substr
3400- *
3401- * @return 0 if ok and negative if error.
3402- *
3403- * @note Be carefull with the what so you get what you want :)
3404- */
3405-int hip_cert_regex(char *what, char *from, int *start, int *stop)
3406-{
3407- int err = 0, status = 0;
3408- regex_t re;
3409- regmatch_t answer[1];
3410-
3411- *start = *stop = 0;
3412-
3413- /* Compiling the regular expression */
3414- if (regcomp(&re, what, REG_EXTENDED)) {
3415- HIP_ERROR("Compilation of the regular expression failed\n");
3416- return -1;
3417- }
3418- /* Running the regular expression */
3419- // TODO this might need to be an error!?
3420- // this needs to be separated to found, not found, and error -Samu
3421- if ((status = regexec(&re, from, 1, answer, 0))) {
3422- err = -1;
3423- goto out_err;
3424- }
3425-
3426- *start = answer[0].rm_so;
3427- *stop = answer[0].rm_eo;
3428-
3429-out_err:
3430- regfree(&re);
3431- return err;
3432-}
3433
3434=== removed file 'lib/core/certtools.h'
3435--- lib/core/certtools.h 2012-01-14 15:29:47 +0000
3436+++ lib/core/certtools.h 1970-01-01 00:00:00 +0000
3437@@ -1,79 +0,0 @@
3438-/*
3439- * Copyright (c) 2010 Aalto University and RWTH Aachen University.
3440- *
3441- * Permission is hereby granted, free of charge, to any person
3442- * obtaining a copy of this software and associated documentation
3443- * files (the "Software"), to deal in the Software without
3444- * restriction, including without limitation the rights to use,
3445- * copy, modify, merge, publish, distribute, sublicense, and/or sell
3446- * copies of the Software, and to permit persons to whom the
3447- * Software is furnished to do so, subject to the following
3448- * conditions:
3449- *
3450- * The above copyright notice and this permission notice shall be
3451- * included in all copies or substantial portions of the Software.
3452- *
3453- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
3454- * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
3455- * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
3456- * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
3457- * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
3458- * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
3459- * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
3460- * OTHER DEALINGS IN THE SOFTWARE.
3461- */
3462-
3463-/**
3464- * @file
3465- * Certificate building, parseing and verification functions.
3466- */
3467-
3468-#ifndef HIPL_LIB_CORE_CERTTOOLS_H
3469-#define HIPL_LIB_CORE_CERTTOOLS_H
3470-
3471-#include <stdint.h>
3472-#include <netinet/in.h>
3473-#include <openssl/rsa.h>
3474-#include <openssl/ossl_typ.h>
3475-#include <sys/types.h>
3476-
3477-#include "protodefs.h"
3478-
3479-
3480-/** Defines */
3481-#define HIP_CERT_CONF_PATH HIPL_SYSCONFDIR "/hip_cert.conf"
3482-
3483-#define HIP_CERT_DAY 86400
3484-
3485-/** Struct used to deliver the minimal needed information to build SPKI cert */
3486-struct hip_cert_spki_info {
3487- hip_tlv type;
3488- hip_tlv_len length;
3489- char public_key[768];
3490- char cert[224];
3491- char signature[768];
3492- struct in6_addr issuer_hit;
3493- /* 0 if successfully verified otherwise negative */
3494- uint32_t success;
3495-};
3496-
3497-/** SPKI cert related functions */
3498-int hip_cert_spki_lib_verify(struct hip_cert_spki_info *);
3499-int hip_cert_spki_create_cert(struct hip_cert_spki_info *,
3500- const char *, struct in6_addr *,
3501- const char *, struct in6_addr *,
3502- time_t *, time_t *);
3503-int hip_cert_spki_char2certinfo(char *, struct hip_cert_spki_info *);
3504-int hip_cert_spki_send_to_verification(struct hip_cert_spki_info *);
3505-
3506-/* x509v3 cert related functions */
3507-int hip_cert_x509v3_request_certificate(struct in6_addr *, unsigned char *);
3508-int hip_cert_x509v3_request_verification(unsigned char *, int);
3509-
3510-/** utility functions */
3511-STACK_OF(CONF_VALUE) *hip_read_conf_section(const char *section_name,
3512- CONF *conf);
3513-CONF *hip_open_conf(const char *filename);
3514-int hip_cert_regex(char *, char *, int *, int *);
3515-
3516-#endif /* HIPL_LIB_CORE_CERTTOOLS_H */
3517
3518=== removed file 'test/certteststub.c'
3519--- test/certteststub.c 2012-01-14 15:29:47 +0000
3520+++ test/certteststub.c 1970-01-01 00:00:00 +0000
3521@@ -1,196 +0,0 @@
3522-/*
3523- * Copyright (c) 2010 Aalto University and RWTH Aachen University.
3524- *
3525- * Permission is hereby granted, free of charge, to any person
3526- * obtaining a copy of this software and associated documentation
3527- * files (the "Software"), to deal in the Software without
3528- * restriction, including without limitation the rights to use,
3529- * copy, modify, merge, publish, distribute, sublicense, and/or sell
3530- * copies of the Software, and to permit persons to whom the
3531- * Software is furnished to do so, subject to the following
3532- * conditions:
3533- *
3534- * The above copyright notice and this permission notice shall be
3535- * included in all copies or substantial portions of the Software.
3536- *
3537- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
3538- * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
3539- * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
3540- * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
3541- * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
3542- * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
3543- * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
3544- * OTHER DEALINGS IN THE SOFTWARE.
3545- */
3546-
3547-/**
3548- * @file
3549- * A teststub for certtools.c/h
3550- *
3551- * File for testing the main operations of certtools.
3552- * First this test takes the default HIT and the corresponding key.
3553- * Secondly it creates a certificate where itself is the issuer and the subject.
3554- * Then it tries to verify it. If it succeeds everything should be OK :)
3555- */
3556-
3557-#include <stdio.h>
3558-#include <stdlib.h>
3559-#include <string.h>
3560-#include <time.h>
3561-#include <arpa/inet.h>
3562-#include <openssl/conf.h>
3563-#include <openssl/ossl_typ.h>
3564-#include <openssl/safestack.h>
3565-
3566-#include "lib/core/certtools.h"
3567-#include "lib/core/debug.h"
3568-#include "lib/core/ife.h"
3569-#include "lib/core/protodefs.h"
3570-
3571-
3572-int main(int argc, char *argv[])
3573-{
3574- int err = 0, i = 0, len;
3575- struct hip_cert_spki_info *cert = NULL;
3576- struct hip_cert_spki_info *to_verification = NULL;
3577- time_t not_before = 0, not_after = 0;
3578- struct hip_common *msg;
3579- struct in6_addr *defhit;
3580- char certificate[1024];
3581- unsigned char der_cert[1024];
3582- CONF *conf;
3583- CONF_VALUE *item;
3584- STACK_OF(CONF_VALUE) *sec = NULL;
3585- STACK_OF(CONF_VALUE) *sec_name = NULL;
3586-
3587- if (argc != 2) {
3588- printf("Usage: %s spki|x509\n", argv[0]);
3589- exit(EXIT_SUCCESS);
3590- }
3591-
3592- HIP_DEBUG("- This test tool has to be run as root otherwise this will fail!\n");
3593- HIP_DEBUG("- Hipd has to run otherwise this will hang!\n");
3594-
3595- HIP_IFEL(!(msg = malloc(HIP_MAX_PACKET)), -1,
3596- "Malloc for msg failed\n");
3597- defhit = malloc(sizeof(struct in6_addr));
3598- if (!defhit) {
3599- goto out_err;
3600- }
3601-
3602- if (strcmp(argv[1], "spki")) {
3603- goto skip_spki;
3604- }
3605-
3606- HIP_DEBUG("Starting to test SPKI certficate tools\n");
3607-
3608- cert = malloc(sizeof(struct hip_cert_spki_info));
3609- if (!cert) {
3610- goto out_err;
3611- }
3612-
3613- to_verification = malloc(sizeof(struct hip_cert_spki_info));
3614- if (!to_verification) {
3615- goto out_err;
3616- }
3617-
3618- time(&not_before);
3619- time(&not_after);
3620- HIP_DEBUG("Reading configuration file (%s)\n", HIP_CERT_CONF_PATH);
3621- conf = hip_open_conf(HIP_CERT_CONF_PATH);
3622- sec = hip_read_conf_section("hip_spki", conf);
3623-
3624- for (i = 0; i < sk_CONF_VALUE_num(sec); i++) {
3625- item = sk_CONF_VALUE_value(sec, i);
3626- if (!strcmp(item->name, "issuerhit")) {
3627- err = inet_pton(AF_INET6, item->value, defhit);
3628- if (err < 1) {
3629- err = -1;
3630- goto out_err;
3631- }
3632- }
3633- if (!strcmp(item->name, "days")) {
3634- not_after += HIP_CERT_DAY * atoi(item->value);
3635- }
3636- }
3637- NCONF_free(conf);
3638-
3639- hip_cert_spki_create_cert(cert,
3640- "hit", defhit,
3641- "hit", defhit,
3642- &not_before,
3643- &not_after);
3644-
3645- /*
3646- * Concatenate everything together as if we would have gotten
3647- * it from someone else and we would be starting to verify.
3648- *
3649- * So the process would be take the cert blob and take out
3650- * public-key sequence, cert sequence and signature sequence
3651- * and create a hip_cert_spki_info and send it to the daemon
3652- * for verification.
3653- */
3654- sprintf((char *) &certificate, "(sequence %s%s%s)",
3655- cert->public_key,
3656- cert->cert,
3657- cert->signature);
3658- HIP_DEBUG("\n\nCertificate gotten back from daemon:\n\n"
3659- "%s\n\nCertificate len %d\n\n",
3660- certificate,
3661- strlen(certificate));
3662-
3663- HIP_IFEL(hip_cert_spki_char2certinfo(certificate, to_verification), -1,
3664- "Failed to construct the hip_cert_spki_info from certificate\n");
3665-
3666- /*
3667- * below, commented out, is the daemons version of the verification
3668- * and below that is the lib version of the verification
3669- */
3670- /*
3671- * HIP_DEBUG("Sending the certificate to daemon for verification\n");
3672- *
3673- * HIP_IFEL(hip_cert_spki_send_to_verification(to_verification), -1,
3674- * "Failed in sending to verification\n");
3675- * HIP_IFEL(to_verification->success, -1,
3676- * "Verification was not successful\n");
3677- * HIP_DEBUG("Verification was successful (return value %d)\n",
3678- * to_verification->success);
3679- */
3680- /* Lets do the verification in library */
3681- HIP_IFEL(hip_cert_spki_lib_verify(to_verification), -1,
3682- "Verification was not successful\n");
3683- HIP_DEBUG("Verification was successful (return value %d)\n",
3684- to_verification->success);
3685-
3686- goto out_err;
3687-
3688-skip_spki:
3689- HIP_DEBUG("Starting to test x509v3 support\n");
3690-
3691- conf = hip_open_conf(HIP_CERT_CONF_PATH);
3692- sec_name = hip_read_conf_section("hip_x509v3_name", conf);
3693-
3694- for (i = 0; i < sk_CONF_VALUE_num(sec_name); i++) {
3695- item = sk_CONF_VALUE_value(sec_name, i);
3696- if (!strcmp(item->name, "issuerhit")) {
3697- err = inet_pton(AF_INET6, item->value, defhit);
3698- if (err < 1) {
3699- err = -1;
3700- goto out_err;
3701- }
3702- }
3703- }
3704- NCONF_free(conf);
3705- len = hip_cert_x509v3_request_certificate(defhit, der_cert);
3706-
3707- /** Now send it back for the verification */
3708- HIP_IFEL((err = hip_cert_x509v3_request_verification(der_cert, len) < 0),
3709- -1, "Failed to verify a certificate\n");
3710-
3711-out_err:
3712- HIP_DEBUG("If there was no errors above, \"everything\" is OK\n");
3713-
3714- free(cert);
3715- free(to_verification);
3716- exit(err);
3717-}
3718
3719=== removed file 'tools/pisacert.c'
3720--- tools/pisacert.c 2011-08-15 14:11:56 +0000
3721+++ tools/pisacert.c 1970-01-01 00:00:00 +0000
3722@@ -1,154 +0,0 @@
3723-/*
3724- * Copyright (c) 2010 Aalto University and RWTH Aachen University.
3725- *
3726- * Permission is hereby granted, free of charge, to any person
3727- * obtaining a copy of this software and associated documentation
3728- * files (the "Software"), to deal in the Software without
3729- * restriction, including without limitation the rights to use,
3730- * copy, modify, merge, publish, distribute, sublicense, and/or sell
3731- * copies of the Software, and to permit persons to whom the
3732- * Software is furnished to do so, subject to the following
3733- * conditions:
3734- *
3735- * The above copyright notice and this permission notice shall be
3736- * included in all copies or substantial portions of the Software.
3737- *
3738- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
3739- * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
3740- * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
3741- * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
3742- * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
3743- * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
3744- * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
3745- * OTHER DEALINGS IN THE SOFTWARE.
3746- */
3747-
3748-/**
3749- * @file
3750- * Generate a SPKI certificate for use with PISA.
3751- */
3752-
3753-#include <errno.h>
3754-#include <stdio.h>
3755-#include <stdlib.h>
3756-#include <string.h>
3757-#include <time.h>
3758-#include <unistd.h>
3759-#include <sys/types.h>
3760-
3761-#include "lib/core/builder.h"
3762-#include "lib/core/certtools.h"
3763-#include "lib/core/icomm.h"
3764-#include "lib/core/ife.h"
3765-#include "lib/core/message.h"
3766-#include "lib/core/protodefs.h"
3767-
3768-
3769-/**
3770- * Get the default hit of the local HIPD.
3771- *
3772- * @param result location to store the result in
3773- * @return 0 on success
3774- */
3775-static int get_default_hit(struct in6_addr *result)
3776-{
3777- int err = 0;
3778- struct hip_common *msg = NULL;
3779- const struct hip_tlv_common *param = NULL;
3780- const struct in6_addr *hit = NULL;
3781-
3782- if (!(msg = hip_msg_alloc())) {
3783- return -1;
3784- }
3785-
3786- HIP_IFE(hip_build_user_hdr(msg, HIP_MSG_GET_DEFAULT_HIT, 0), -1);
3787- HIP_IFE(hip_send_recv_daemon_info(msg, 0, 0), -ECOMM);
3788-
3789- param = hip_get_param(msg, HIP_PARAM_HIT);
3790- hit = hip_get_param_contents_direct(param);
3791- memcpy(result, hit, sizeof(struct in6_addr));
3792-
3793-out_err:
3794- free(msg);
3795- return err;
3796-}
3797-
3798-/**
3799- * Create the certificate with the given parameters.
3800- *
3801- * @param not_before start of certificate lifetime
3802- * @param not_after end of certificate lifetime
3803- * @param hit HIT of issuer and subject
3804- * @param certificate buffer to store the resulting certificate in
3805- * @param size size of the certificate buffer
3806- * @return 0 on success
3807- */
3808-static int create_certificate(time_t *not_before, time_t *not_after,
3809- struct in6_addr *hit, char *certificate,
3810- size_t size)
3811-{
3812- int err = 0;
3813- struct hip_cert_spki_info cert;
3814-
3815- HIP_IFEL(!not_before || !not_after || !hit || !certificate, -1,
3816- "NULL parameter found.\n");
3817-
3818- hip_cert_spki_create_cert(&cert, "hit", hit, "hit", hit, not_before,
3819- not_after);
3820-
3821- snprintf(certificate, size, "(sequence %s%s%s)", cert.public_key,
3822- cert.cert, cert.signature);
3823-out_err:
3824- if (err != 0 && certificate) {
3825- certificate[0] = '\0';
3826- }
3827- return err;
3828-}
3829-
3830-int main(int argc, char *argv[])
3831-{
3832- time_t not_before = 0, not_after = 0;
3833- struct in6_addr hit;
3834- int err = 0, days = 0;
3835- FILE *f = NULL;
3836- char certificate[1024] = "";
3837- size_t cert_len, cert_out;
3838-
3839- HIP_IFEL(argc != 3, -1, "Wrong number of arguments.\n");
3840-
3841- HIP_IFEL(getuid() != 0, -1, "You're not superuser.\n");
3842-
3843- days = atoi(argv[1]);
3844- HIP_IFEL(days <= 0, -1, "Specify a positive number of days.\n");
3845-
3846- f = fopen(argv[2], "w");
3847- HIP_IFEL(f == NULL, -1, "Could not write to file.\n");
3848-
3849- time(&not_before);
3850- time(&not_after);
3851- not_after += days * 24 * 60 * 60;
3852-
3853- HIP_IFEL(get_default_hit(&hit), -1, "Could not get HIT from hipd.\n");
3854- HIP_IFEL(create_certificate(&not_before, &not_after, &hit,
3855- certificate, sizeof(certificate)) != 0,
3856- -1, "Could not create the certificate.\n");
3857-
3858- cert_len = strlen(certificate);
3859- cert_out = fwrite(certificate, cert_len, 1, f);
3860- if (cert_len != cert_out) {
3861- HIP_ERROR("Failed to write certificate to file\n");
3862- err = -1;
3863- }
3864-
3865-out_err:
3866- if (err == -1) {
3867- fprintf(stderr, "usage: pisacert days filename\n");
3868- fprintf(stderr, "must be run as superuser, e.g. with sudo\n");
3869- }
3870-
3871- if (f) {
3872- fclose(f);
3873- }
3874-
3875- return err;
3876-}

Subscribers

People subscribed via source and target branches

to all changes: