id_manager: Use calloc instead of malloc
[strongswan.git] / src / charon-tkm / src / tkm / tkm_diffie_hellman.c
1 /*
2 * Copyrigth (C) 2012 Reto Buerki
3 * Copyright (C) 2012 Adrian-Ken Rueegsegger
4 * Hochschule fuer Technik Rapperswil
5 *
6 * This program is free software; you can redistribute it and/or modify it
7 * under the terms of the GNU General Public License as published by the
8 * Free Software Foundation; either version 2 of the License, or (at your
9 * option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>.
10 *
11 * This program is distributed in the hope that it will be useful, but
12 * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
13 * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
14 * for more details.
15 */
16
17 #include <tkm/client.h>
18 #include <tkm/constants.h>
19
20 #include "tkm.h"
21 #include "tkm_diffie_hellman.h"
22
23 #include <utils/debug.h>
24
25 typedef struct private_tkm_diffie_hellman_t private_tkm_diffie_hellman_t;
26
27 /**
28 * Private data of a tkm_diffie_hellman_t object.
29 */
30 struct private_tkm_diffie_hellman_t {
31
32 /**
33 * Public tkm_diffie_hellman_t interface.
34 */
35 tkm_diffie_hellman_t public;
36
37 /**
38 * Diffie Hellman group number.
39 */
40 u_int16_t group;
41
42 /**
43 * Diffie Hellman public value.
44 */
45 dh_pubvalue_type pubvalue;
46
47 /**
48 * Context id.
49 */
50 dh_id_type context_id;
51
52 };
53
54 METHOD(diffie_hellman_t, get_my_public_value, void,
55 private_tkm_diffie_hellman_t *this, chunk_t *value)
56 {
57 *value = chunk_alloc(this->pubvalue.size);
58 memcpy(value->ptr, &this->pubvalue.data, value->len);
59 }
60
61 METHOD(diffie_hellman_t, get_shared_secret, status_t,
62 private_tkm_diffie_hellman_t *this, chunk_t *secret)
63 {
64 dh_key_type shared_secret;
65 if (ike_dh_get_shared_secret(this->context_id, &shared_secret) != TKM_OK)
66 {
67 return FAILED;
68 }
69
70 *secret = chunk_alloc(shared_secret.size);
71 memcpy(secret->ptr, &shared_secret.data, secret->len);
72 return SUCCESS;
73 }
74
75
76 METHOD(diffie_hellman_t, set_other_public_value, void,
77 private_tkm_diffie_hellman_t *this, chunk_t value)
78 {
79 // TODO: unvoid this function
80
81 dh_pubvalue_type othervalue;
82 othervalue.size = value.len;
83 memcpy(&othervalue.data, value.ptr, value.len);
84
85 ike_dh_generate_key(this->context_id, othervalue);
86 }
87
88 METHOD(diffie_hellman_t, get_dh_group, diffie_hellman_group_t,
89 private_tkm_diffie_hellman_t *this)
90 {
91 return this->group;
92 }
93
94 METHOD(diffie_hellman_t, destroy, void,
95 private_tkm_diffie_hellman_t *this)
96 {
97 if (ike_dh_reset(this->context_id) != TKM_OK)
98 {
99 DBG1(DBG_LIB, "failed to reset DH context %d", this->context_id);
100 }
101
102 tkm->idmgr->release_id(tkm->idmgr, TKM_CTX_DH, this->context_id);
103 free(this);
104 }
105
106 /*
107 * Described in header.
108 */
109 tkm_diffie_hellman_t *tkm_diffie_hellman_create(diffie_hellman_group_t group)
110 {
111 private_tkm_diffie_hellman_t *this;
112
113 INIT(this,
114 .public = {
115 .dh = {
116 .get_shared_secret = _get_shared_secret,
117 .set_other_public_value = _set_other_public_value,
118 .get_my_public_value = _get_my_public_value,
119 .get_dh_group = _get_dh_group,
120 .destroy = _destroy,
121 },
122 },
123 .group = group,
124 .context_id = tkm->idmgr->acquire_id(tkm->idmgr, TKM_CTX_DH),
125 );
126
127 if (!this->context_id)
128 {
129 free(this);
130 return NULL;
131 }
132
133 if (ike_dh_create(this->context_id, group, &this->pubvalue) != TKM_OK)
134 {
135 free(this);
136 return NULL;
137 }
138
139 return &this->public;
140 }